[PythonCAD] Post nineteenth release plans

Art Haas ahaas at airmail.net
Wed Nov 17 01:33:18 CET 2004

On Tue, Nov 16, 2004 at 05:15:48PM -0600, Eric Wilhelm wrote:
> # The following was supposedly scribed by
> # Art Haas
> # on Tuesday 16 November 2004 09:24 am:
> >A better approach
> >would be to save the file with a temporary name, and if that save is
> >successful then make the backup and rename the temporary file to the
> >correct name. This way, the existing file is not tampered with until
> > the new file has been completely saved, so any glitches in saving
> > the new file will not require you to rename a backup copy.
> One caveat in this scheme:  You cannot save into a symlink (or a hard 
> link for that matter.)
True. If you look at the current file saving code in 'imageio.py',
you'll see that there is an effort being made already to not write into
symbolic links. However, the code wouldn't pass a security audit as the
symlink could be added after the test was done but before the file is
actually opened.

What I'm starting to do is change the 'save_image' function to take an
open filehandle instead of a filename. First, this change will move any
file manipulations out of this function, and secondly it will allow
this function to be used to write the file info out to a filehandle that
could be attached to a pipe.

> Maybe this is solved by getting all of the XML into an in-memory 
> string, and then open(file, 'w') the file and write into it.  
> However, here I'm assuming that your main concern about failed saves 
> is during creation of the XML.
That is most of it. I'd hate to lose a drawing because the file save
operation failed whether due to a bug in the code or possibly some disk
space issue. Imaging losing hours or days worth of work that way. Ugh.

> If you really need an atomic write action, then you would have to 
> follow a symlink back to the original and perform your os.rename() 
> operation there.  However, readlink() only works on symlinks, not 
> hard links, so this scheme doesn't do everything that open(file, 'w') 
> does.

I'm still not fond of the idea of writing through a symbolic link. It
seems like doing that is asking for trouble.

> Let's forget about links for a second and just note that using a 
> rename will lose any existing permissions on a file, creating 
> problems where a file is shared between users (if I set a file as a+r 
> and that is not the default of my umask, then pythoncad will make my 
> setting go away whenever I save.)  There is also an issue of who 
> saves the file (I believe any user can write into a file with a+w 
> permissions, but only the owner can remove it (or move, or rename on 
> top of it.))  Also, note the implications of same on your backup file 
> strategy.  Maybe you need to actually open() the backup and then read 
> the current file into it, then open() the destination file and write 
> the new XML.  Then, as long as you have write permission on both 
> files, everything is okay, regardless of who owns them.

Typically it is the ownership and permissions on the directory that
control renaming and deleting files, but your points about file
permissions and ownership are all good ones. There are lots of different
scenarios that can happen, and almost certainly the way that saving
files is changed is going to have drawback in some of the scenarios.
If two different users have write access to a file, I can't think of a
way to prevent them from saving over each other's changes.

I'll hopefully have some code to show this week and having a few people
take a look and offer suggestions would be great. If someone could post
some pseudo-code for ways they've implemented file saving routines in
programs they have written, or routines that they've found to be robust,
that would be great too. Maybe a few examples of good examples could be
listed as well - possibly people can recommend some KDE, GNOME, or other
open source program.

Man once surrendering his reason, has no remaining guard against absurdities
the most monstrous, and like a ship without rudder, is the sport of every wind.

-Thomas Jefferson to James Smith, 1822

More information about the PythonCAD mailing list