I have one question of temporary file open in C program.
I know there is FOPEN_MAX in stdio.h. As far as I know, FOPEN_MAX is the number of files(not temporary) can be opened simultaneously in C program. But, If I make temporary file using 'tmpfile()', does the number of temporary files included in FOPEN_MAX ?
Thanks in advance.
It is not written explicitly, but it seems the limitation is the same, no matter if file is temporary or not.
https://www.opennet.ru/man.shtml?topic=tmpfile&category=3&russian=5
See error code for tmpfile():
EMFILE
{FOPEN_MAX} streams are currently open in the calling process.
Related
This question already has answers here:
How to create a temporary directory in C in Linux?
(2 answers)
Closed 3 years ago.
I'm writing tests for a library that need to create a directories to test some functional it should provide. I did some research and found that there is a library function:
#include <stdio.h>
char *tmpnam(char *s);
And it is possible to call it with NULL to unique path. The problem is the linker warns me as follows:
warning: the use of `tmpnam' is dangerous, better use `mkstemp'
Also as suggested in this answer to use the function. But this hardcoding /tmp in the beginning looks strage. Also checking the environment variables TMP, TMPDIR, etc looks complicated.
Maybe there is some POSIX function which checks theses variables for me? Also is there any other pitfalls of using tmpnam except shared static buffer and race conditions?
The tmpnam() function doesn't create a directory; it generates a file name that didn't exist at somewhere about the time it was invoked, but which may exist by the time you try to use it with mkdir(), which does create directories. There is typically a plethora of related functions for doing roughly the same job, but they're different on each platform.
POSIX does provide mkdtemp() and mkstemp() — the former creates a directory, the latter a file; the same page documents both — where you specify the template to the function. That leaves you in charge of the directory within which the directory or file is created.
With both mkstemp() and mkdtemp(), the directory containing the new file or directory must already exist.
One of the primary problems with using tmpnam() is that you have essentially no control over where the file is created or what the filename looks like. Almost all the other functions give you some measure of control. Not being thread-safe is usually not a major issue — you can provide a buffer that will be used, making it thread-safe.
I'm having trouble wrapping my head around files in C, specifically scope and duration. Say I create a file using
fopen("random.dat", "w");
How long does this file exist for? Does it get deleted once my program is finished running, or is it somehow reset? If I reopen the file further down in my code, only this time with the "r" reading argument, or "a", will I have conflicting streams since I'm opening a file that is already technically opened?
It's a normal file, just like all the other files on your computer. It exists until something deletes it, and its contents stay the same until something modifies it. It's not automatically deleted or "reset" when the program finishes. (C would be useless as a programming language if it couldn't save data to files that last longer than the program.)
However, since you're opening the file with the "w" option, the file will be truncated (reset to zero length) if it already exists — effectively, fopen deletes the existing file and creates a new empty one. That means that if you run your program a second time, the output from the first run will be replaced with the output from the second.
The effect of opening the same file more than once at the same time is platform-specific. On Unix/Linux it should work fine, but on Windows it may fail (though I haven't checked). But if you close the file (e.g. with fclose) before opening it again, that should work properly on any system.
The term file scope is used during compilation of a C program. It has nothing to do with something during execution.
Actually, the term is missleading; a better phrase would be compilation unit scope. It describes the visibility of names (variables, functions, structs, ... ) defined outside of a block (statement), i.e. at the outermost level.
For files opened during program execution, they are open actually until closed explicitly, independent from the program structure. However, as you required an object holding a reference to the file, that does restrict visibility to where you have access to this reference (FILE * for the stdlib file-functions), either by scope, or by explicitly passing it to functions.
A normal file opened/written/closed will dwefinitively not stop existing after the program closes or its reference goes out of scope (how could you store data persistently?), but only if explicitly deleted/unlinked or the filesystem itself is deleted (e.g. for Linux tempfs, which only exists until the OS is shut down). This is called lifetime, btw.
I am doing a c programming assignment where I am working with command-line arguments. One of the notes says that if the file you work with (to my understanding, it will always be "list.csv") is not yet created to create one. Just like vim does when you write "vim new.txt" and new.txt does not exist yet.
I am just wondering if there is a function that tests for the existence of a file? Or do I use some sort of try/catch block?
you can use fopen(). the second parameter says, what to do. Read, create+write, append+create(if not existent)
one way is to use fstat() on the filename.
under UNIX try 'man fstat'
Typically when you want to write to a file the library or operating system API will automatically try to create it for you if it does not already exist. Exactly how you can control this depends on the API that you will be using.
Is it safe to read directory entries via readdir() or scandir() while files are being created or deleted in this directory? Should I prefer one over the other?
EDIT: When I say "safe" I mean entries returned by these functions are valid and can be operated without crashing the program.
Thanks.
It depends by what you mean as "safe". They are safe in the sense that they should not crash your program. However, if you are creating/deleting files as you are reading/scanning that directory, the set of files you get back might not be up-to-date.
When reading/scanning a directory for directory entries, the file pointer (a directory is just a special type of file), moves forward. However, depending upon the file system, there may be nothing to prevent new files from being created in an empty directory entry slot behind your file pointer. Consequently, newly added directory entries may not be immediately detected by readdir()/scandir(). Similar reasoning applies for file deletion / directory entry removal.
Hope this helps.
What's your definition of safety? You won't crash the system, and readdir/scandir won't crash your program. Although they might give you data that is immediately out of date.
The usual semantics for reading a directory are that if you read the directory from beginning to end, you will see all of the files that didn't change during that time exactly once, and you will see files that were created or deleted during that time at most once.
On UNIX-like systems readdir() and scandir() are library functions implemented on top of the same underlying system call (getdents() in Linux, getdirentries() in BSD). So there shouldn't be much difference in their behavior in this regard. I think readdir() is a bit more standard, and therefore will be more portable.
I am trying to write a program that allows a binary to be run, substituting a certain file when requested with another. It is a library with simple replacements for the system call functions, that is used with LD_PRELOAD. The problem is that it catches opens for reading (the substitute file is read instead), but writes always go back to the actual, specified file. Are there any other "open" system calls I should know about?
Nevermind -- stupid mistake.
Wasn't checking both absolute and relative paths...
I am not sure what the cause of your problem is, but using strace on your program might give some insight. It should be part of any sane Linux distribution.
If it's open for writing, it's most likely going through the creat function (I'm guessing fopen would be redirecting you there). Check your fcntl.h for a complete list.
substituting a certain file when requested with another
Sounds like you check only for the input file (do you check by filename?). You need to check and substitute the output file, too.
If you output goes to one of the standard outputs, then you need to close and reopen them with your output substitute) before you fork into the executable.
To find all system calls that your executable makes you can use strace.
To find all library calls that your executable makes you can use ltrace.