C Programming/stdio.h/fopen
fopen, as implemented in glibc and musl will use the open system call.
Opening a file using fopen
[edit | edit source]A file is opened using fopen
, which returns an I/O stream attached to the specified file or other device from which reading and writing can be done. If the function fails, it returns a null pointer.
The related C library function freopen
performs the same operation after first closing any open stream associated with its parameters.
They are defined as
FILE *fopen(const char *path, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *fp);
The fopen
function is essentially a slightly higher-level wrapper for the open
system call of Unix operating systems. In the same way, fclose
is often a thin wrapper for the Unix system call close
, and the C FILE
structure itself often corresponds to a Unix file descriptor. In POSIX environments, the fdopen
function can be used to initialize a FILE
structure from a file descriptor; however, file descriptors are a purely Unix concept not present in standard C.
The mode
parameter to fopen
and freopen
must be a string that begins with one of the following sequences:
mode | description | starts.. | ||
---|---|---|---|---|
r | rb | open for reading (The file must exist) | beginning | |
w | wb | open for writing (creates file if it doesn't exist). Deletes content and overwrites the file. | beginning | |
a | ab | open for appending (creates file if it doesn't exist) | end | |
r+ | rb+ | r+b | open for reading and writing (The file must exist) | beginning |
w+ | wb+ | w+b | open for reading and writing. If file exists deletes content and overwrites the file, otherwise creates an empty new file | beginning |
a+ | ab+ | a+b | open for reading and writing (append if file exists) | end |
The "b" stands for binary. The C standard provides for two kinds of files—text files and binary files—although operating systems are not required to distinguish between the two. A text file is a file consisting of text arranged in lines with some sort of distinguishing end-of-line character or sequence (in Unix, a bare line feed character; in Microsoft Windows, a carriage return followed by a line feed). When bytes are read in from a text file, an end-of-line sequence is usually mapped to a linefeed for ease in processing. When a text file is written to, a bare linefeed is mapped to the OS-specific end-of-line character sequence before writing. A binary file is a file where bytes are read in "raw", and delivered "raw", without any kind of mapping.
When a file is opened with update mode ( '+' as the second or third character in the mode argument), both input and output may be performed on the associated stream. However, writes cannot be followed by reads without an intervening call to fflush
or to a file positioning function (fseek
, fsetpos
, or rewind
), and reads cannot be followed by writes without an intervening call to a file positioning function.[1]
Writing and appending modes will attempt to create a file of the given name, if no such file already exists. As mentioned above, if this operation fails, fopen
will return NULL
.
Glibc/musl notes
[edit | edit source]Musl and Glibc support the e mode on Linux, which sets O_CLOEXEC on the new file descriptor. O_CLOEXEC is a Linux 2.6 feature, documented in the Linux man-pages project:
Enable the close-on-exec flag for the new file descriptor. Specifying this flag permits a program to avoid additional fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag. Additionally, use of this flag is essential in some multithreaded programs since using a separate fcntl(2) F_SETFD operation to set the FD_CLOEXEC flag does not suffice to avoid race conditions where one thread opens a file descriptor at the same time as another thread does a fork(2) plus execve(2).
See http://danwalsh.livejournal.com/53603.html
See musl cgit for the Musl implementation.