C++ filter: How do I get a filename from a FILE * pointer?
-
Is there a way to find out the filename associated with a specific FILE * pointer? (OS: Red Hat EL 5) I'm running into a strange bug where we verify that a file exists and then about two or three lines later, when we try to rename the file, we get an error that says there is no such file. The code is something like the following...... FILE *fp; char temp_filename[MAX_NAME_LENGTH]; char perm_filename[MAX_NAME_LENGTH]; ... fp = fopen(temp_filename, "w"); ... // done writing to temp file, move it to permanent file if(fp) { fclose(fp); if (rename(temp_filename, perm_filename)) { cout << "Error: can't rename file: " << strerror(errno) << endl; } } The strerror command shows "No such file or directory," which is a head-scratcher because fp is open and we are in the if block of code to begin with. I'm trying to find out if the file has been moved or deleted out from under me, i.e. if temp_filename is still the filename associated with fp. For debugging, I've tried to do a stat on temp_filename and an fstat on fp, and then cout the inode numbers (st_ino) to see if they are the same, but I can't get it to compile since the first argument to fstat(int, struct stat *) needs to be an int, not a FILE pointer. The target operating system, if it matters, is RHEL 5, x86_64. Help, please.
-
Answer:
the only C++ is the cout statement /nitpick You can get the fd from the FILE* for your fstat. http://linux.die.net/man/3/fileno What's the real error value (errno) ? And what does the man page say about the meaning of the error ? http://linux.die.net/man/2/rename Any goofy things in the path ? (spurious dots, slashes, etc) Are they relative paths or full paths ?
tckma at Ask.Metafilter.Com Visit the source
Other answers
You don't have test case files on which you can run this? If you're absolutely confident the filenames are valid, my only remaining advice is to add a huge sleep between the fclose and the rename, then while it is spinning issue a "sync" from the command line in a shell. When you fclose, the filename is not guaranteed to exist at that (or, technically any) point: you may, in fact, be renaming a file that doesn't yet exist on disk (you need to fsync on the containing directory's handle in order to have that guarantee).
introp
Btw, opening a file to check xxx (existence and especially permissions) and then closing it and doing something with some file that has the same name is classically wrong.
rr
When the operation fails, print both filenames (with delimiters so we can see leading/trailing spaces) in the error message, then provide that to us, please.
introp
Right, and none of that prevents you from doing everything in memory via a stream/buffer, and only doing the write out for the consuming process (to the perm_filename) when you're done, no ? Now, that's not answering your question which sounds like your tempfile is not there on disk (for some reason), even after closing the file pointer. Does adding a flush to the FILE* help any ? Are you writing to some area that gets whacked repeatedly ? Are you using mktemp() viz some roll-your-own temp file name ? http://linux.die.net/man/3/mktemp (introp: based on the fstat() answer, it *appears* the problem is all on the temp file side, the file pointer is mostly legit, but the underlying file/path isn't. I'm taking OP on faith that the paths are legit and permissions are OK for now. )
k5.user
1. man fileno stat link unlink mkstemp and fdopen 2. perr and strerror are your friend 3. You do not need fsync. Avoid voodoo programming. 4. Don't use mktemp, use mkstemp
rr
Yes, but my sleep vote was just to do a trivial test. Since you have to fsync the directory handle, it's a non-trivial amount of code to add. Simple test first; if it works, fix it in code.
introp
If I adapt Rhomboid's code, I get output like: fd 4 has filename '' Error: Cannot rename file /some/dir/.blah to /some/dir/blah -- exiting...
tckma
Also inotify could help you watch what's going on in your directory. Find some tools that use it. Here in debian-ish land, "inotify-tools" and "iwatch" packages do a lot.
cmiller
No, we have code specifically telling it to leave dot files alone.
tckma
Related Q & A:
- How do I get a value from a JObject?Best solution by Stack Overflow
- How do I get a sponsor for a charity marathon?Best solution by Yahoo! Answers
- How can I get a loan without a job?Best solution by Yahoo! Answers
- How do I get a job as a vineyard worker in France?Best solution by Yahoo! Answers
- How do I get a job with a cruise line?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.