This question already has answers here:
C fopen vs open
(11 answers)
Closed 8 years ago.
There are differences between open() and fopen() function. One is system call and other is library function. I try to figure out what is the application of these two function but I found nothing useful. Can you give some scenarios where to use open() and where fopen() should be used?
Sometimes you need a file descriptor. open() gives you one. Sometimes you need a FILE*, in which case use fopen(). You can always turn your FILE* into a file descriptor via fileno(), whereas the opposite transformation is not really supported. It mostly depends on what downstream functions you intend to call with the file handle.
open() will return the file descriptor. We overwrite the file, while using the fopen() we cannot overwrite the file. We use the file descriptor for reading and writing using the other
functions like read() write() etc. But in fopen() it will return file descriptor we have to
use fprintf() to write to the file stream. sscanf() to read from the stream.
Related
According to this documentation, the temporary file created by tmpfile() is closed and deleted when the program exits normally. So far, I have not found any details regarding the use of fclose() on such file.
Is it safe to use fclose() on a temporary file created by tmpfile()?
Yes, OK to close.
The tmpfile function creates a temporary binary file that is different from any other existing file and that will automatically be removed when it is closed or at program termination. If the program terminates abnormally, whether an open temporary file is removed is implementation-defined.
C17dr ยง 7.21.4.3 2
Edited: Thanks #ShadowRanger
It is always safer to close it.
I had used tmpfile() multiple times and had always did fclose().
You need to fclose() whether you use tmpfile() or tmpfile64().
This question already has answers here:
What's the difference between a file descriptor and a file pointer?
(9 answers)
Closed 4 years ago.
My understanding is that both fopen() and open() can be used to open files. open() returns a file descriptor. But they should be equivalent in terms of get a file for writing or reading. What is the purpose of definining the file descriptors? It is not clear from the wiki page.
https://en.wikipedia.org/wiki/File_descriptor
fopen returns a FILE * which is a wrapper around the file descriptor (I will ignore the "this is not required by the specification" aspect here, as I am not aware of an implementation that does not do this). At a high level, it looks like this:
application --FILE *--> libc --file descriptor--> kernel
Shells operate directly on file descriptors mainly because they are executing other programs, and you cannot modify the other program's FILE * objects. However, you are able to modify other program's file descriptors using the dup syscall at startup (i.e. between fork and exec). For example:
/bin/cat > foo.txt
This tells the shell to execute the /bin/cat program, but first redirect stdout (file descriptor #1) to a file that it opens. This is implemented as (pseudocode):
if (fork() == 0) {
int fd = open("foo.txt");
dup2(fd, 1);
exec("/bin/cat");
}
The closest thing you can do with FILE * is calling freopen, but this is not persisted when using exec unlike file descriptors.
But why do we need FILE * at all then, if it's just a wrapper around a file descriptor? One main benefit is having a readahead buffer. For example, consider fgets. This will eventually call the read syscall on the file descriptor associated with the FILE * that you pass in. But how does it know how much to read? The kernel has no option to say "give me one line" (line-buffered ttys aside). If you read more than one line in the first read, the next time you call fgets you might only get part of the next line, since the kernel has already given you the first part in the previous read syscall. The other option would be calling read one character at a time, which is horrible for performance.
So what does libc do? It reads a bunch of characters at once, then stores the extra characters in an internal buffer on the FILE * object. The next time you call fgets, it is able to use the internal buffer. This buffer is also shared with functions like fread, so you can interleave calls to fgets and fread without losing data.
The two function at different levels:
open() is a lower-level, POSIX function to open a file. It returns a distinct integer to identify, and enable access to, the file opened. This integer is a file descriptor.
fopen() is a higher-level, portable, C standard-library function to open a file.
On a POSIX system, the portable fopen() probably calls the nonportable open(), but this is an implementation detail.
When in doubt, prefer fopen().
For more information, on a Linux system, man 2 read. The POSIX read() function reads data via the file descriptor returned by open().
This question already has answers here:
Difference between fclose and close
(4 answers)
Closed 6 years ago.
I want to redirect STDOUT to a file on the disk. The point is to make the printf on my program write to a file instead of the console.
I saw some articles on the web where they used:
dup2(fileno(outputFile), STDOUT_FILENO);
Or:
close(STDOUT_FILENO);
dup(fileno(outputFile));
In every tutorial they use close() and it actually works. But I was curious and I tried to use fclose(stdout) instead but some error happened when I tried to use printf:
fclose(STDOUT_FILENO);
dup(fileno(outputFile));
Error:
Bad file descriptor
My question is, why does fclose() not work but close() does?
Thanks.
STDOUT_FILENO is a numeric file descriptor (usually 1). When you use close, you release the descriptor, but then reassign it with dup2. Any output to that descriptor will now go to the new file.
stdout on the other hand is a FILE*, an object of sorts that contains a file descriptor. Doing printf formats output into a buffer associated with the FILE, and then writes the buffer to the descriptor (depending upon the buffering mode). When you fclose a FILE*, it (normally) closes the underlying descriptor, and frees the FILE object. The dup2 does not ressurect stdout, so printf fails.
This question already has answers here:
What happens if I don't call fclose() in a C program?
(4 answers)
Closed 8 years ago.
Suppose that we have opened a file using fopen() in C and we unintentionally forget to close it using fclose() then what could be the consequences of it? Also what are the solutions to it if we are not provided with the source code but only executable?
The consequences are that a file descriptor is "leaked". The operating system uses some descriptor, and has some resources associated with that open file. If you fopen and don't close, then that descriptor won't be cleaned up, and will persist until the program closes.
This problem is compounded if the file can potentially be opened multiple times. As the program runs more and more descriptors will be leaked, until eventually the operating system either refuses or is unable to create another descriptor, in which case the call to fopen fails.
If you are only provided with the executable, not the source code, your options are very limited. At that point you'd have to either try decompiling or rewriting the assembly by hand, neither of which are attractive options.
The correct thing to do is file a bug report, and then get an updated/fixed version.
If there are a lot of files open but not closed properly, the program will eventually run out of file handles and/or memory space and crash.
Suggest you engage your developer to update their code.
The consequences is implementation dependent based on the fclose / fopen and associated functions -- they are buffered input/output functions. So things write are written to a "file" is in fact first written to an internal buffer -- the buffer is only flushed to output when the code "feels like it" -- that could be every line, every write of every full block depending on the smartness of the implementation.
The fopen will most likely use open to get an actual file descriptor to the operating system -- on most systems (Linux, Windows etc) the os file descriptor will be closed by the OS when the process terminates -- however if the program does not terminates, the os file descriptor will leak and you will eventually run out of file descriptors and die.
Some standard may mandate a specific behavior when the program terminates either cleanly or through a crash, but the fact is that you cannot reply in this as not all implementations may follow this.
So your risk is that you will loose some of the data which you program believed that it had written -- that would be the data which was sitting in the internal buffer but never flushed -- or you may run out of file descriptors and die.
So, fix the code.
If I fopen a file, what's the difference between calling fclose or close and which one should I use?
If forked children have access to the file as well, what should they do when they are finished with the file?
fclose() is function related with file streams. When you open file with the help of fopen() and assign stream to FILE *ptr. Then you will use fclose() to close the opened file.
close() is a function related with file descriptors. When you open file with the help of open() and assign descriptor to int fd. Then you will use close() to close the opened file.
The functions like fopen(), fclose() etc are C standard functions, while the other category of open(), close() etc are POSIX-specific. This means that code written with open(), close() etc is not a standard C code and hence non-portable. Whereas the code written with fopen(), fclose etc is a standard code and can be ported on any type of system.
which one should I use?
It depends on how you opened the file. If you open a file with fopen(), you should use fclose() and if you open file with open(), you should use close().
If forked children have access to the file as well, what should they do when they are finished with the file?
This is also dependent on where you made the fork() call: before opening the file or after opening it.
See: Are file descriptors shared when fork()ing?
See: man fclose and man close
open() and close() are UNIX syscalls which return and take file descriptors, for use with other UNIX syscalls such as write(). fopen() and fclose() are standard C library functions which operate on FILE*s, for use with things like fwrite and fprintf. The latter are almost always what you should be using: They're simpler and more cross-platform.
As for your second question, forked children have the same numeric file descriptor as the parent, but it's a copy; they can close it, and it will still be open for the parent and other children. (Though personally, I don't like to have files open when I fork()... I like to make that sort of shared resource usage explicit. Pipes, of course, are an exception.)
which one should I use?
If you open a file with fopen, close it with fclose. Using close in this case may cause a memory leak on a handle allocated by fopen