I have to use a certain cross-platform library which passes FILE*
objects around.
I get a file descriptor from another source (inherited), I want to keep same fd
across fork
'd processes.
I currently use fdopen
to convert a file descriptor to a FILE*
object.
My problem is that fclose
used to clean up FILE*
objects closes connected file descriptor.
I would very much like to keep this file descriptor after it has been used.
is there a way rescue file descriptor from FILE*
?
Is there a way to detach it?
Or a way to substitute a file descriptor in FILE*
with a dummy?
P.S. this needs to be cross-platform, well across POSIX anyway.
Supposing that fd
is your file descriptor and f
your FILE* got from it. Maybe something like the following will do the trick:
fd2 = dup(fd);
fclose(f);
dup2(fd2, fd);
close(fd2);
My problem is that fclose
used to clean up FILE*
objects closes
connected file descriptor.
You could use dup(2)
to get a copy of the descriptor. Then the close(2)
that fclose(3)
does won't do anything.
I need to maintain exact same fd number
Then call dup2
again after fclose
: dup2(savedfd, rescuedfd)
When you get a file descriptor from another source, Try to get its filename from that file descriptor. (Some says its possible using platform specific method. -google it.)
Once you get filename then fopen it again and get FILE* and do your work and clean up it using fclose.
Your original fd will not be disturbed.
Here's a non-portable idea (vote if you think this is good/best):
GNU libc provides fopencookie
and BSD provides equivalent funopen
.
These return real FILE*
handle, but implementation is your own:
It is then relatively trivial to map read/write/seek/close functions to underlying system calls:
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!