У меня есть программа на C ++, которая открывает файлы в / tmp (в системе * nix) и читает их содержимое.
Для этого я использую:
ofstream dest;
dest.open(abs_path.c_str(), ios::app);
где abs_path — строка, содержащая абсолютный путь к файлу.
Проблема в том, что некоторые программы * nix создают именованные каналы в виде файлов в / tmp. Например,
/tmp/vgdb-pipe-to-vgdb-from-23732-by-myusername-on-???
Это канал, созданный утилитой отладки, которую я использую.
в документация для ofstream, метод open говорит, что метод устанавливает бит ошибки, когда открытие файла не удается. Однако в моих тестах он вместо этого зависает, пытаясь открыть файл (который на самом деле представляет собой канал) на неопределенный срок. Я предполагаю, что это потому, что файл заблокирован другой программой (вероятно, отладчиком).
Так, Как я могу заставить ofstream :: open блокировать в течение ограниченного периода времени или нет вообще? Это достаточно легко, чтобы изящно очистить, если он выходит из строя, но он должен действительно потерпеть неудачу в первую очередь ..
Простой ответ заключается в том, что вы не можете. filebuf::open
(вызывается
ofstream
) в основном делегаты на ОС, и предполагается, что ОС будет
сделать правильную вещь. И интерфейс, который он поддерживает, очень, очень
ограничено; много важных вариантов open
(O_SYNC
, O_NONBLOCK
, так далее)
не отображаются, и, следовательно, не могут быть использованы. Единственные решения, которые я нашел для
это либо использовать std::ostringstream
, а затем записать строку в
файл с использованием вызовов системного уровня, или написать свой собственный streambuf
, который
делает то, что я хочу (гораздо проще, чем кажется, так как вы обычно только
нужна часть чего filebuf
предложения — вам часто не нужно
двунаправленность, поиск или перевод кода).
Конечно, ни одно из этих решений не является портативным.
Наконец, я не уверен, почему вы пишете в /tmp
, Условно,
все, что вы положили в /tmp
должен содержать идентификатор процесса. И для
Из соображений безопасности я бы всегда создавал подкаталог с идентификатором процесса
от его имени, и с очень ограниченными правами доступа, и создавать любые
временные файлы в нем.
AFAIK, нет такой вещи, как неблокирующий ввод, определенный языком C ++. (Есть метод std :: streambuf :: in_avail (), но все равно он вам не поможет)
Вы можете рассмотреть возможность использования метода C
int file_descr = open( "pipe_addr", O_RDONLY |O_NONBLOCK);
вместо std :: ofstream