Можно ли спасти файловый дескриптор из FILE*?
Я должен использовать определенную кроссплатформенную библиотеку, которая проходит FILE*
объекты вокруг.
Я получаю дескриптор файла из другого источника (унаследованный), я хочу сохранить тот жеfd
через fork
делаю процессы.
Я сейчас пользуюсь fdopen
преобразовать дескриптор файла в FILE*
объект.
Моя проблема в том что fclose
используется для очистки FILE*
Объект закрывает дескриптор подключенного файла.
Я бы очень хотел сохранить этот файловый дескриптор после его использования.
Есть ли способ спасти дескриптор файла из FILE*
?
Есть ли способ отсоединить его?
Или способ заменить дескриптор файла в FILE*
с пустышкой?
PS это должно быть кроссплатформенным, хорошо в любом случае POSIX.
4 ответа
Моя проблема в том что
fclose
used to clean upFILE*
Объект закрывает дескриптор подключенного файла.
Вы могли бы использовать dup(2)
to get a copy of the descriptor. Тогда close(2)
тот fclose(3)
does won't do anything.
I need to maintain exact same fd number
Тогда позвони dup2
снова после fclose
: dup2(savedfd, rescuedfd)
Если предположить, что fd
Ваш файловый дескриптор и f
ваш файл * получил от него. Может быть, что-то вроде следующего поможет?
fd2 = dup(fd);
fclose(f);
dup2(fd2, fd);
close(fd2);
Когда вы получаете файловый дескриптор из другого источника, попробуйте получить его имя файла из этого файлового дескриптора. (Некоторые говорят, что это возможно, используя метод, специфичный для платформы. - Google.)
Как только вы получите имя файла, снова откройте его и получите FILE*, сделайте свою работу и очистите его с помощью fclose.
Ваш оригинальный FD не будет нарушен.
Вот непереносимая идея (проголосуйте, если считаете, что это хорошо / лучше):
GNU libc обеспечивает fopencookie
и BSD обеспечивает эквивалент funopen
,
Эти возвращают настоящие FILE*
обрабатывать, но реализация ваша собственная:
Тогда довольно просто сопоставить функции чтения / записи / поиска / закрытия с базовыми системными вызовами:
read/readfn(cookie, buf, size){ return read((int)cookie, buf, size); }
write/writefn(cookie, buf, size) { return write((int)cookie, buf, size); }
seek/seekfn(cookie, offs, arg) { return seek((int)cookie, offs, arg); } // may require arg mapping to whence
close/closefn(cookie) {} // that's the whole point!