emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Race-condition ?


From: Gaëtan LEURENT
Subject: Re: Race-condition ?
Date: Sun, 26 Jun 2005 00:25:56 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (usg-unix-v)

David Kastrup wrote on 24 Jun 2005 23:01:50 +0200:

> I fail to see the advantage of using chown, or using fopen and
> fchown.  In both cases the file name can be changed to refer to
> something else before the operation starts.
>
> The only situation where fchown offers any advantage is where you
> _already_ have a file open, like when you write the file after fopen,
> and then change its permissions.

Yes, that is true. But we are exactly in the situation were fchown is
useful.

> That is, the owner change must be accomplished in something like
> write-region, or it is pointless.  As an isolated operation,
> fopen/fchown offers no advantage whatsoever.

Yes, fopen/fchown would be the same as calling chown. But here we have
just created a new file, and we want to change it's owner, so this
should be done with fchown.

The code is:

|  Fcopy_file (file, newname,
|                /* We have already prompted if it was an integer,
|                   so don't have copy-file prompt again.  */
|                NILP (ok_if_already_exists) ? Qnil : Qt,
|               Qt, Qnil);
|
|  /* Preserve owner and group, if possible (if we are root).  */
|  if (stat (SDATA (encoded_file), &data) >= 0)
|    chown (SDATA (encoded_file), data.st_uid, data.st_gid);
|
|  Fdelete_file (file);

So, we first open a file and write something in it inside Fcopy_file,
then we call chown on the same path. But the file that is at this path
could be something else that what the we created in Fcopy_file. We
should keep that file open, and call fchown on its filedescriptor,
instead of calling chown on it's path.

This will need some change in Fcopy_file, to be able to do something
with the filedescriptor before the file is closed; the most easy way
seems to make a subroutine that does the job of Fcopy_file and returns
the fd before closing it, and use this subroutine both in Fcopy_file and
here in Frename_file.


We also have the same kind of thing inside Fcopy_file (and this one is
also in stable emacs) where we call chmod on the file path just after
closing the file.
[I have replaced some part of the code with //... to make it shorter]

|  #ifdef VMS
|  // ...
|  #else
|  #ifdef MSDOS
|  // ...
|  #else  /* not MSDOS */
|    ofd = emacs_open (SDATA (encoded_newname),
|                   O_WRONLY | O_TRUNC | O_CREAT
|                   | (EQ (mustbenew, Qexcl) ? O_EXCL : 0),
|                   0666);
|  #endif /* not MSDOS */
|  #endif /* VMS */
|    if (ofd < 0)
|      report_file_error ("Opening output file", Fcons (newname, Qnil));
|  
|    record_unwind_protect (close_file_unwind, make_number (ofd));
|  
|    immediate_quit = 1;
|    QUIT;
|    while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
|      if (emacs_write (ofd, buf, n) != n)
|        report_file_error ("I/O error", Fcons (newname, Qnil));
|    immediate_quit = 0;
|  
|    /* Closing the output clobbers the file times on some systems.  */
|    if (emacs_close (ofd) < 0)
|      report_file_error ("I/O error", Fcons (newname, Qnil));
|  
|    if (input_file_statable_p)
|      {
|        if (!NILP (keep_time))
|       {
|               // ...
|       }
|  #ifndef MSDOS
|        chmod (SDATA (encoded_newname), st.st_mode & 07777);
|  #else /* MSDOS */
|  // ...
|  #endif /* MSDOS */
|      }

Here the change is very easy: we should just do fchmod(ofd,...) before
emacs_close(ofd).

-- 
Gaëtan LEURENT




reply via email to

[Prev in Thread] Current Thread [Next in Thread]