XEmacs 21.4.19: Problem with customized folders on Windows XP

Antonio Freixas tonyf
Sun Nov 12 21:55:48 EST 2006


stephen at xemacs.org wrote:

> Tony Freixas writes:
>
>  > The right solution is to fix XEmacs to recognize the Windows access
>  > control model. I have the source code for XEmacs but have never tried
>  > working with it--if someone could point me to the right modules to look
>  > at, I could try to fix this. If this is a nasty problem to fix, let
me know.
>
> I would guess that you're looking for src/fileio.* for generic
> low-level functions, sysdep.* or syswindows.* for Windows drivers
> where they're different from POSIX or too low level to be in libc.
> There may be some relevant code at the Lisp level.  Sorry I can't be
> more specific, but OS hacking is not my strong point.

I thought I'd follow up with what I've found:

    In src/fileio.c, we have:

    DEFUN ("file-writable-p", Ffile_writable_p, 1, 1, 0, /*
    Return t if file FILENAME can be written or created by you.
    */
           (filename))
    {
      /* This function can GC.  GC checked 1997.04.10. */
      Lisp_Object abspath, dir;
      Lisp_Object handler;
      struct stat statbuf;
      struct gcpro gcpro1;

      CHECK_STRING (filename);
      abspath = Fexpand_file_name (filename, Qnil);

      /* If the file name has special constructs in it,
         call the corresponding file handler.  */
      GCPRO1 (abspath);
      handler = Ffind_file_name_handler (abspath, Qfile_writable_p);
      UNGCPRO;
      if (!NILP (handler))
        return call2 (handler, Qfile_writable_p, abspath);

      if (xemacs_stat ((char *) XSTRING_DATA (abspath), &statbuf) >= 0)
        return (check_writable ((char *) XSTRING_DATA (abspath))
            ? Qt : Qnil);


      GCPRO1 (abspath);
      dir = Ffile_name_directory (abspath);
      UNGCPRO;
      return (check_writable (!NILP (dir) ? (char *) XSTRING_DATA (dir)
                  : "")
          ? Qt : Qnil);
    }

The way I read this, it says that the file is checked to see if it
exists. If not, the directory in which the file would be created is
checked to see if it is writable. So I looked up check_writable:

    /* Return nonzero if file FILENAME exists and can be written.  */

    static int
    check_writable (const char *filename)
    {
    #ifdef HAVE_EACCESS
      return (eaccess (filename, W_OK) >= 0);
    #else
      /* Access isn't quite right because it uses the real uid
         and we really want to test with the effective uid.
         But Unix doesn't give us a right way to do it.
         Opening with O_WRONLY could work for an ordinary file,
         but would lose for directories.  */
      return (access (filename, W_OK) >= 0);
    #endif
    }

It used the eaccess() or access() functions which are part of unistd.h.
Searching the internet, I found the following:

    On NTFS, the DACL in the file descriptor determines the access
permissions of a file. However, the DOS file attribute for read-only
overrides the DACL -- if the read-only attribute is set, the write
access is denied, even if otherwise allowed by the DACL.

On NTFS, access control seems to be a complicated beast. The old DOS
permission attributes are retained, but may not reflect actual file
permissions. What the above statement says is that, if the DOS
permission says the file (or directory) is read-only, then the access()
method will echo this, even if the DACL would say that the file is writable.

The solution requires using Win32 API calls to determine the true file
permission, rather than relying on access() or eaccess().

Since I've never worked with either the XEmacs code or the Win32 API, I
don't feel confident or capable of fixing this problem. For my own use,
I can comment out the directory check in the file-writable-p function
and live with some odd errors if the directory really is read-only.

If any Win32 experts would like to tackle this, I would certainly
appreciate it.

-- 
Antonio Freixas
tonyf at europa.com




More information about the XEmacs-Beta mailing list