Unix Programming - Renaming an open file

This is Interesting: Free IT Magazines  
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'.

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com