How to get a FILE pointer from a file descriptor?
Asked Answered
A

3

98

I'm playing around with mkstemp(), which provides a file descriptor, but I want to generate formatted output via fprintf(). Is there an easy way to transform the file descriptor provided by mkstemp() into a FILE * structure that is suitable for use with fprintf()?

Abiogenetic answered 21/12, 2009 at 17:30 Comment(1)
And the inverse: How can I convert a file pointer ( FILE* ) to a file descriptor (fd)?Fruitless
C
122

Use fdopen():

FILE* fp = fdopen(fd, "w");
Clarineclarinet answered 21/12, 2009 at 17:31 Comment(11)
And to get the file descriptor from a FILE* use fileno() : linux.die.net/man/3/filenoThresher
if fd was opened with some flags (like O_NONBLOCK) -- what will happen with them after fdopen opens it with new flags? Will they be xor-ed together or substituted?Broadfaced
Not available in ANSI C.Uncircumcised
@jww: File descriptors are not ANSI C to begin with.Rachmaninoff
and is there a way to close a file with the fd?Immovable
If you mean close(fd), that's not a good idea. fclose(fp) should be used to make sure any buffered output (if any) is written.Clarineclarinet
is it bad in any way to call fdopen multiple times? (assuming it happens inside some function which gets called again and again)Saxecoburggotha
You don't want to fdopen() the same file descriptor twice. Each instance will have separate buffers that will cause your input/output to get messed up.Clarineclarinet
@RichardPennington I think multiple fdopen calls are fine depending on what underlies the file descriptor. For a tty or a socket this may actually be desirable since ANSI C has requirements for fseek/fgetpos/fflush calls between input and output. Here it seems different streams for input and output are the best way to go. This essentially happens with stdin/stdout/stderr anyway on a terminal device - the file descriptors refer to the same file description. See experts-exchange.com/questions/24261206/…Skirl
@Broadfaced The options for the FILE* have to be within the scope of the already open file descriptor. So if you have opened fd with read only, and the FILE* with write only, it should throw an exception. For more info refer to ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/…Imbecilic
@TjadClark "it should throw an exception" - that would be difficult seeing as fdopen() is a C function and C has no native exceptions mechanism.Proa
A
32

FILE* f = fdopen(d, "w");

man fdopen output:

SYNOPSIS

#include <stdio.h>

FILE *
fdopen(int fildes, const char *mode);

The fdopen() function associates a stream with the existing file descriptor, fildes. The mode of the stream must be compatible with the mode of the file descriptor. When the stream is closed via fclose(3), fildes is closed also.

Azeria answered 21/12, 2009 at 17:32 Comment(2)
Not available in ANSI C.Uncircumcised
For more clarity, refer to ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/…Imbecilic
E
-8

There is no standard way of doing this (or the reverse) as the C Standard has nothing to say about file descriptors. Your specific platform may or may not provide such a mechanism.

Exportation answered 21/12, 2009 at 17:32 Comment(15)
Depends on what you mean by "standard". POSIX is a standard.Clarineclarinet
though, The fdopen() function conforms to IEEE Std 1003.1-1988 (``POSIX.1'').Azeria
The question was about file descriptors. ;-)Clarineclarinet
@Neil > you might be right, you didn't help the OP with your answerAzeria
@Gregory I helped him assuming that he wants to write portable code. And downvoting technically correct answers is not good practice.Exportation
@Richard The question is tagged as C, not Posix. Posix is a platform, not a language, standard.Exportation
@Neil > I didn't vote down, indeed there is nothing wrong in what you said.Azeria
@Neil > the question being tagged as C doesn't mean "tell me the holly truth about the C standard" but rather "I'm coding in C, I fail at doing this, please tell me whether it is possible and how?"Azeria
There is a posix tag here on SO, with 193 questions. Having said that, I think Neil's answer is correct. More people should be using posix tag. And it's a good idea to remind people what exactly "C" is. While we're at it, we should make people realize that there's nothing like "C/C++", and that these are two different languages.Instantaneous
@Neil > it looks like you have fans though, as several of my answers are being downvoted right now :)Azeria
I'm backing away slowly... Now turning and running away.Clarineclarinet
@Gregory: For the record, it wasn't me. There are some weird downvoting issues here on SO. My posts #1898871 and https://mcmap.net/q/130293/-memory-corruption/… were downvoted, and I don't know why!Instantaneous
I agree that there's no standard way of doing this, but the OP's mention of mkstemp implies that non-standard solutions are acceptable in this particular instance. In that case, however, he should have added the posix tag (which I see has since been added).Mechling
@Neil, and the purpose of the Net and the meaning of life. You would make more sense if you've said that you are of different opinion. I also doubt SO is all about hairsplitting over standards. And it's not very practical to rely on tagging skills of someone with an SO-experience corresponding to the reputation of 23.Underlet
Not sure why this fellow is getting downvoted. ANSI C does not have fdopen, so there's no way to convert a file descriptor to a FILE* in a base system. You'd need a different standard to get the functionality.Uncircumcised

© 2022 - 2024 — McMap. All rights reserved.