|
Home > Archive > Unix Programming > April 2005 > Renaming an open file
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Renaming an open file
|
|
| Christian 2005-04-12, 6:02 pm |
| Hello,
On linux, my program writes some stuff in a log file, which is rotated using
the logrotate utility.
I wonder what could happen if the file is renamed in between the opening and
the writing to that file. That is :
- myprog opens the log file
- logrotate rotates the log file (rename it and create a new empty one)
- myprog writes to the log file
I've done some test and the writing is correctly done to the newly renamed
file test.txt.new.
#include <stdio.h>
int main() {
FILE *fp = fopen( "/var/tmp/test.txt", "a" );
rename( "/var/tmp/test.txt", "/var/tmp/test.txt.new" );
fprintf( fp, "TEST" );
fclose( fp );
return 0;
}
I got 2 questions :
- can I safely assume that the above piece of code will never crash ?
- is this behaviour due to the fact that the inode is preserved when a file
is renamed on the same file system ?
Thanks in advance.
Christian
| |
| Rich Teer 2005-04-12, 6:02 pm |
| On Tue, 12 Apr 2005, Christian wrote:
> I wonder what could happen if the file is renamed in between the opening and
> the writing to that file. That is :
>
> - myprog opens the log file
> - logrotate rotates the log file (rename it and create a new empty one)
> - myprog writes to the log file
>
> I've done some test and the writing is correctly done to the newly renamed
> file test.txt.new.
Yes, that is correct.
> I got 2 questions :
> - can I safely assume that the above piece of code will never crash ?
Well, never say never... :-)
But it is pretty safe. The only time a process looks at the file NAME is
when you pass that name to open().
> - is this behaviour due to the fact that the inode is preserved when a file
> is renamed on the same file system ?
Yes; renaming a file across file systems *might* be problematic, though.
-
Rich Teer, SCNA, SCSA, OpenSolaris CAB member
President,
Rite Online Inc.
Voice: +1 (250) 979-1638
URL: http://www.rite-group.com/rich
| |
| Ralf Fassel 2005-04-12, 6:02 pm |
| * "Christian" <cgregoir99@yahoo.com>
| - can I safely assume that the above piece of code will never crash?
`fp' might be NULL after the fopen, disk might be full after
successful fopen etc, so the general answer to this general question
is `No'.
| - is this behaviour due to the fact that the inode is preserved when
| a file is renamed on the same file system ?
Once you have successfully opened a file, the file descriptor remains
valid in your program until you close the file. Even if the disk file
is removed in between, you can still write to the file descriptor.
R'
| |
| Richard Kettlewell 2005-04-12, 6:02 pm |
| "Christian" <cgregoir99@yahoo.com> writes:
> - can I safely assume that the above piece of code will never crash ?
No. If the fopen fails for any reason then the fprintf call will
probably crash.
--
http://www.greenend.org.uk/rjk/
| |
| Christian 2005-04-12, 6:02 pm |
|
"Richard Kettlewell" <rjk@greenend.org.uk> a écrit dans le message de
news:wwv4qecez6g.fsf@rjk.greenend.org.uk...
> "Christian" <cgregoir99@yahoo.com> writes:
>
> No. If the fopen fails for any reason then the fprintf call will
> probably crash.
>
OK, I should have specified that the piece of code was just an example,
written in the shortest form for simplicity' sake ... and that when I said
'never', I meant 'when writing to a renamed file'.
Anyway, thanks for the replies.
| |
| Chuck Dillon 2005-04-12, 6:02 pm |
| Christian wrote:
> Hello,
>
> On linux, my program writes some stuff in a log file, which is rotated using
> the logrotate utility.
>
> I wonder what could happen if the file is renamed in between the opening and
> the writing to that file. That is :
>
> - myprog opens the log file
> - logrotate rotates the log file (rename it and create a new empty one)
> - myprog writes to the log file
>
> I've done some test and the writing is correctly done to the newly renamed
> file test.txt.new.
>
> #include <stdio.h>
>
> int main() {
>
> FILE *fp = fopen( "/var/tmp/test.txt", "a" );
>
> rename( "/var/tmp/test.txt", "/var/tmp/test.txt.new" );
>
> fprintf( fp, "TEST" );
>
> fclose( fp );
>
> return 0;
> }
>
>
> I got 2 questions :
> - can I safely assume that the above piece of code will never crash ?
Nope, at least not until you add some code that checks that your fopen
succeeded.
> - is this behaviour due to the fact that the inode is preserved when a file
> is renamed on the same file system ?
Yes, sort of. Rename doesn't do anything to the file. It changes a
directory entry that refers to the file. You can unlink/delete
"/var/tmp/test.txt" and not affect the file or the already opened fp
stream.
It's not unusual for a program to open a temporary file and immediately
remove the link if it knows it will never again need to refer to it via
the file system. That way the temporary file doesn't have to be
removed on exit, it won't persist in the event of a crash and no other
process can mess with it.
-- ced
>
> Thanks in advance.
>
> Christian
>
>
--
Chuck Dillon
Senior Software Engineer
NimbleGen Systems Inc.
| |
| Moshe Jacobson 2005-04-12, 6:02 pm |
| Christian <cgregoir99@yahoo.com> wrote:
> I wonder what could happen if the file is renamed in between the opening and
> the writing to that file.
When you open a file, it opens a file handle to the file on disk.
Keep in mind that filenames are also just pointers to the file on
disk. So when you open a file, it basically "dereferences" the
filename and gets you the actual file pointer. When you rename the
file, it's just changing that other pointer that you're no longer
using.
If, however, you move the file to another file system, the file on the
source drive will remain open until you close it, even if the filename
is gone from that directory. That is because a file will not be
deleted until all file handles to it are closed. The move process
copies the file to the other file system then unlinks the filename.
But your program still has a pointer open to the file, so you could
theoretically fill up your hard drive and have no record of what file
contains all that data! Oh, and yes, this has happened to me too.
Improper log rotation on a busy logfile means your program is still
logging to a file that no longer has a filename associated with it.
Weird stuff, that.
Moshe
--
*** SPAM BLOCK: Remove bra before replying! ***
http://runslinux.net :: moshe at runslinux dot net :: AIM: Jehsom
| |
| Pete Kazmier 2005-04-14, 7:51 am |
| "Christian" <cgregoir99@yahoo.com> writes:
> On linux, my program writes some stuff in a log file, which is
> rotated using the logrotate utility.
>
> I wonder what could happen if the file is renamed in between the
> opening and the writing to that file. That is :
>
> - myprog opens the log file
> - logrotate rotates the log file (rename it and create a new empty one)
> - myprog writes to the log file
One thing to keep in mind, if myprog is a daemon that will run
forever, and logrotate has rotated the original log file from 'mylog'
to 'mylog.1', the data written by myprog will continue to be appended
to mylog.1, which is what your open file descriptor refers to. You
will not see any data added to 'mylog' until you explicitly close your
original file descriptor, and reopen the log file.
To avoid this behavior, a common idiom is to catch a SIGHUP signal in
your program, and then in the handler, you close and reopen the log
file. Then as part of the postrotate directive of logrotate, you do a
'kill -1' to your daemon. That will ensure that logging messages are
now being directed to the newly created log file 'mylog'.
|
|
|
|
|