http://www.perlmonks.org?node_id=427627

ctilmes has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to do an atomic update of a file using Net::SFTP.

Typically what I would do is write to "file.tmp", then rename to "file" when complete.

What I find is that Net::SFTP::do_rename() fails if the file I am renaming to already exists. If I use do_remove() of the old file prior to the do_rename() it all works fine, but then there is an (albeit small) window between the do_remove() and do_rename() where the file doesn't exist.

Is there some other technique I should be using to update the file over SFTP?

Replies are listed 'Best First'.
Re: Net::SFTP atomic updates?
by grinder (Bishop) on Feb 03, 2005 at 14:15 UTC
    Net::SFTP::do_rename() fails if the file I am renaming to already exists

    Is that so? If that's the case, then file a bug report.

    Renaming to a file that already exists is not an error, indeed, the POSIX rename function mandates that at all points in time, a file named 'file' will always exist, even in the event of a system crash at the point in time when the system rename call is in progress. Depending on the exact point in time you ask for the file, you might get the old one, or the new one, but you are guaranteed that you will get one of them. Break that, and you break a lot of things.

    Wietse Venema reminded me of this point on the Postfix Users mailing list just yesterday :)

    - another intruder with the mooring in the heart of the Perl

Re: Net::SFTP atomic updates?
by ctilmes (Vicar) on Feb 03, 2005 at 15:05 UTC
    Ok, a little more info... I'm using OpenSSH, and the version I am using implements an older version of the SFTP protocol that required it to throw an error when the file you are renaming to already exists (which it does). There has since been a revision to the SFTP protocol spec (draft-ietf-secsh-filexfer-06.txt) that allows you to specify optional flags to the rename command that can force it to atomically rename one file to an already existing file (which is what I want to do.)

    Sounds like I am SOL until 1) I get an SFTP server implementing the new spec and 2) Net::SFTP supports the new spec.

Re: Net::SFTP atomic updates?
by samizdat (Vicar) on Feb 03, 2005 at 14:08 UTC
    Are you speaking of replacing the file on your local machine or the remote? If it's local, use File::Copy.