On Mon, 2005-12-05 at 17:11 -0500, Derek Atkins wrote:
> Quoting Tim Wunder <[EMAIL PROTECTED]>:
> > As I understand the process, gnucash renames the existing file, then 
> > creates a new file of the same name, then chowns it to whatever the
> > permissions of the original file was. This seems really odd to me.

"chowns it to whatever owner and group", and "chmod to set the
permission mode".

> It's not odd at all.  LOTS of programs do this.  Emacs does this,
> for example.  It will rename() the old file to the tilde-file,
> and then create the new file and write your new data to it.  Then
> it reverts the file permissions to the original version.

Emacs has a setting for 'backup by copying'.  This is useful if you need
to edit files that have more than one directory entry, or hard link, and
you _do_ _not_ want the hard-link broken by edit/save.

On the Linux file system, the files data location, size, ownership and
permissions are specified by it's "inode" (See:
http://en.wikipedia.org/wiki/Inode).  The directory entries specify the
file name and which inode contains the file information.  More than one
directory entry can point to a particular inode, and the inode contains
a link count which tells how many directory entries point to that file.
The unlink() (man unlink) system call removes a directory entry and
decrements the link count in the inode.  When it reaches zero, the
blocks consumed by that file are freed for reuse by the file system.
When a file is opened (man open) the link count is incremented, and when
it's closed (man close) the link count is decremented.  That is why you
can open a file, unlink it, and keep using it, even though there is no
longer a directory entry referring to it.  When the invisible file is
closed, its blocks will be released.

If you use the rename() (man rename, and man mv) system call, it changes
the file name in the directory entry.  If you then open a new file using
the original file's old name, the operating system creates a brand new
inode for that file.  Thus, the old name no longer points to the same
file that other directory entries still point to, aka, hard links to
that file are broken.  (Symbolic links to that file are not broken,
since they point to the file by _name_, rather than by _inode_.)

In my experience, hard links are not used very often, except in cases
where you actually do want to break the link if you change the file in
one location.  Perhaps you have a tree of source code, and you then make
a tree of hard links to it.  The new tree won't take up more space,
since the directory entries point to the same inodes as the ones in the
original tree.  If you want to edit a file in the new tree without
affecting the original file, you must rename the file, then make a copy
of it under the original name, and edit that.  If you want the edit to
show up in both places, you must ensure that Emacs is set to 'backup by
copying' mode.  (What does 'vim' do here?)

Since the ownership, permissions and POSIX ACL attributes (man acl) are
all associated with the inode rather than the directory entry, when you
rename the old file to a new name then open a new file under the old
name, you must then set the ownership and permissions of the newly
created inode.  In the POSIX API, that is done with separate system
calls --- it is not part of open().

Since the only system call guaranteed to be atomic over NFS is rename(),
if there are concurrent file access issues, it may be that special care
must be taken to ensure that two processes on separate computers do not
race for access to the file.  You can read about that by researching
Debian Policy regarding mail spool file locking on NFS.  ;-)

If there are security issues, like a race to access and open this new
file before it's permissions are set, then the file should be kept in a
secure sub-directory where only the appropriate users may access any
files created there.

Also see: man ln, man 2 stat

> > Why is a new data file created at all? Why isn't the original data 
> > file simply copied (like a cp -a) to the backup file.
> 
> "cp" is a command-line utility.  There is no "cp" API function.

You may like to get a copy of the GNU Shellutils source, and have a look
at what 'cp' actually does.  Another one to look at is the 'cp' in
Busybox; it's a little simpler, but does basically the same thing.

> > Derek's suggestion to not chown at all and "forego the group setting
> > completely and assume the user has a proper setgid setting on the directory"
> > seems reasonable to me.

There may be cases where that assumption is not correct, I think.  For
the general case, and to err on the side of caution, it's probably best
to set all of owner, group, mode, and ACL attributes.  If ACL is not
being dealt with by the application, and the administrator wants to use
them, then I suppose they can be set for the directory...?

-- 
Karl Hegbloom <[EMAIL PROTECTED]>

_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to