B.4 Relation to Standard C Library I/O Functions

We mentioned earlier that the standard C library I/O functions are implemented on top of these low-level I/O functions. Sometimes, though, it's handy to use standard library functions with file descriptors, or to use low-level I/O functions on a standard library FILE* stream. GNU/Linux enables you to do both.

If you've opened a file using fopen, you can obtain the underlying file descriptor using the fileno function. This takes a FILE* argument and returns the file descriptor. For example, to open a file with the standard library fopen call but write to it with writev, you could use this code:

 
FILE* stream = fopen (filename, "w"); 
int file_descriptor = fileno (stream); 
writev (file_descriptor, vector, vector_length); 

Note that stream and file_descriptor correspond to the same opened file. If you call this line, you may no longer write to file_descriptor:

 
fclose (stream); 

Similarly, if you call this line, you may no longer write to stream:

 
close (file_descriptor); 

To go the other way, from a file descriptor to a stream, use the fdopen function. This constructs a FILE* stream pointer corresponding to a file descriptor. The fdopen function takes a file descriptor argument and a string argument specifying the mode in which to create the stream. The syntax of the mode argument is the same as that of the second argument to fopen, and it must be compatible with the file descriptor. For example, specify a mode of r for a read file descriptor or w for a write file descriptor. As with fileno, the stream and file descriptor refer to the same open file, so if you close one, you may not subsequently use the other.