niXforums Forum Index
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   PreferencesPreferences   Log in to check your private messagesLog in to check your private messages   Log inLog in 
·  nixdoc.net ·  man pages ·  Linux HOWTOs ·  FreeBSD Tips ·  Forums
navigation Forum index » Programming » Unix internals
rename(2) without unlinking old file
Post new topic   Reply to topic Page 1 of 1 [4 Posts] View previous topic :: View next topic
Author Message
Urs Thuermann
*nix forums beginner


Joined: 15 Mar 2005
Posts: 40

PostPosted: Mon May 02, 2005 3:33 pm    Post subject: rename(2) without unlinking old file Reply with quote

Is there a way to rename(2) a file only if the new name does not
already exist, i.e. without unlinking the file that had the new name
before? When I do

touch a b
mv a b

the old file named b is unlinked and the file a replaces b, atomically
with a call to rename(2). Is there a way to make sure, no file is
unlinked when I call rename(2)?

First checking with stat(2) and calling rename(2) only if stat returns
ENOENT doesn't do this, because it's not atomic. Between
stat("new-name", ...) and rename("old-name", "new-name") the file
"new-name" might be created.

urs
Back to top
Lew Pitcher
*nix forums Guru


Joined: 21 Feb 2005
Posts: 675

PostPosted: Mon May 02, 2005 4:22 pm    Post subject: Re: rename(2) without unlinking old file Reply with quote

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Urs Thuermann wrote:
Quote:
Is there a way to rename(2) a file only if the new name does not
already exist, i.e. without unlinking the file that had the new name
before? When I do

touch a b
mv a b

the old file named b is unlinked and the file a replaces b, atomically
with a call to rename(2). Is there a way to make sure, no file is
unlinked when I call rename(2)?

First checking with stat(2) and calling rename(2) only if stat returns
ENOENT doesn't do this, because it's not atomic. Between
stat("new-name", ...) and rename("old-name", "new-name") the file
"new-name" might be created.

I would think that you could accomplish this through judicious use of link(2)
and unlink(2). Something like

IF link(old_name,new_name) succeeds
unlink(old_name)

link(2) should fail if the new_name already exists


- --
Lew Pitcher
IT Specialist, Enterprise Data Systems,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFCdm/5agVFX4UWr64RAgiUAJ0XZsR990QRmpSchEW9ShJdmogccgCg5Bbu
3ItwBOhdsXcWZ1Ovfd3sK1k=
=TGhD
-----END PGP SIGNATURE-----
Back to top
Andrew Smallshaw
*nix forums beginner


Joined: 23 Feb 2005
Posts: 26

PostPosted: Mon May 02, 2005 7:06 pm    Post subject: Re: rename(2) without unlinking old file Reply with quote

In article <m24qdlzg5a.fsf@janus.isnogud.escape.de>, Urs Thuermann wrote:
Quote:
Is there a way to rename(2) a file only if the new name does not
already exist, i.e. without unlinking the file that had the new name
before? When I do

touch a b
mv a b

the old file named b is unlinked and the file a replaces b, atomically
with a call to rename(2). Is there a way to make sure, no file is
unlinked when I call rename(2)?

If we're talking about within the same directory, or even the same filesystem,
a link(), followed by an unlink() will do what you want since link() is
non-clobbering. Across filesystems it doesn't really matter since the file
will need to be copied over before you can delete the original. [1]

One health warning though: some systems allow you to 'merge' an existing
directory with a freshly mounted filesytem. I've never played around with
this because I've always considered it dangerous, but if the directory in
question is somewhere that might be a mount point do your own research.

--
Andrew Smallshaw
andrews@sdf.lonestar.org

[1] Yes, you can have an open file that has been unlinked. But if we're
talking about data integrity are you going to take that chance?
Back to top
Urs Thuermann
*nix forums beginner


Joined: 15 Mar 2005
Posts: 40

PostPosted: Thu May 05, 2005 5:07 am    Post subject: Re: rename(2) without unlinking old file Reply with quote

Lew Pitcher <Lew.Pitcher@td.com> writes:

Quote:
I would think that you could accomplish this through judicious use of link(2)
and unlink(2). Something like

IF link(old_name,new_name) succeeds
unlink(old_name)

link(2) should fail if the new_name already exists

Thanks. As it is that simple I wonder why I hadn't seen this myself.
The reason for my question was that GNU mv does the following when
calling mv foo bar, which is not safe:

...
umask(0) = 022
stat64("bar", 0xbffffa38) = -1 ENOENT (No such file or directory)
brk(0x8053000) = 0x8053000
lstat64("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat64("bar", 0xbffff904) = -1 ENOENT (No such file or directory)
rename("foo", "bar") = 0
_exit(0)


urs
Back to top
Google

Back to top
Display posts from previous:   
Post new topic   Reply to topic Page 1 of 1 [4 Posts] View previous topic :: View next topic
The time now is Fri Jan 09, 2009 6:37 am | All times are GMT
navigation Forum index » Programming » Unix internals
Jump to:  

Similar Topics
Topic Author Forum Replies Last Post
No new posts Running php file everyday on scheduled time sachin PHP 1 Fri Jul 21, 2006 12:49 pm
No new posts Regarding thesaurus iso file Srikanth modules 0 Fri Jul 21, 2006 10:42 am
No new posts how can i get a file descriptor not used? mars system 0 Fri Jul 21, 2006 7:41 am
No new posts small GTK "Open file" dialog David Siroky Debian 0 Fri Jul 21, 2006 7:30 am
No new posts Trouble Declaring 3D Array in Header File free2klim C++ 1 Fri Jul 21, 2006 4:07 am

Loans | Personal Injury Attorney Los Angeles | Loans | Bankruptcy | Weight Loss
Copyright © 2004-2005 DeniX Solutions SRL
 
Other DeniX Solutions sites: Unix/Linux blog |  electronics forum |  medicine forum |  science forum | 
Privacy Policy


Powered by phpBB © 2001, 2005 phpBB Group
[ Time: 0.1645s ][ Queries: 16 (0.0795s) ][ GZIP on - Debug on ]