On Cygwin, two files with the same ACL can have different mode: $ ls -l tmpfile1 -rwxr-x--- 1 haible None 14 Jun 2 22:06 tmpfile1 $ getfacl.exe tmpfile1 # file: tmpfile1 # owner: haible # group: None user::rw- group::r-x mask:rwx other:--- $ echo foo > tmpfile2 $ chmod 650 tmpfile2 $ getfacl.exe tmpfile2 # file: tmpfile2 # owner: haible # group: None user::rw- group::r-x mask:rwx other:--- $ ls -l tmpfile1 tmpfile2 -rwxr-x--- 1 haible None 14 Jun 2 22:06 tmpfile1 -rw-r-x--- 1 haible None 4 Jun 2 22:08 tmpfile2
Therefore, on Cygwin, unlike on Solaris, after an ACL has been set, the 'chmod' call must be performed, even if the mode is a subset of 0777. 2008-06-08 Bruno Haible <[EMAIL PROTECTED]> Add support for Cygwin ACLs. * lib/acl-internal.h (MODE_INSIDE_ACL): New macro for Solaris-like API. * lib/set-mode-acl.c (qset_acl) [!MODE_INSIDE_ACL]: Don't optimize away the chmod_or_fchmod call. * lib/copy-acl.c (qcopy_acl) [!MODE_INSIDE_ACL]: Likewise. *** lib/acl-internal.h.orig 2008-06-08 16:49:30.000000000 +0200 --- lib/acl-internal.h 2008-06-08 16:44:43.000000000 +0200 *************** *** 160,165 **** --- 160,173 ---- # elif HAVE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ + /* Set to 1 if a file's mode is implicit by the ACL. + Set to 0 if a file's mode is stored independently from the ACL. */ + # if defined __CYGWIN__ /* Cygwin */ + # define MODE_INSIDE_ACL 0 + # else /* Solaris */ + # define MODE_INSIDE_ACL 1 + # endif + /* Return 1 if the given ACL is non-trivial. Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ extern int acl_nontrivial (int count, aclent_t *entries); *** lib/copy-acl.c.orig 2008-06-08 16:49:30.000000000 +0200 --- lib/copy-acl.c 2008-06-08 16:49:17.000000000 +0200 *************** *** 330,337 **** if (count == 0) return qset_acl (dst_name, dest_desc, mode); ! did_chmod = 0; /* set to 1 once the mode bits in 0777 have been set, ! set to 2 once the mode bits other than 0777 have been set */ saved_errno = 0; /* the first non-ignorable error code */ /* If both ace_entries and entries are available, try SETACL before --- 330,336 ---- if (count == 0) return qset_acl (dst_name, dest_desc, mode); ! did_chmod = 0; /* set to 1 once the mode bits in 0777 have been set */ saved_errno = 0; /* the first non-ignorable error code */ /* If both ace_entries and entries are available, try SETACL before *************** *** 371,377 **** free (ace_entries); # endif ! if (did_chmod <= ((mode & (S_ISUID | S_ISGID | S_ISVTX)) ? 1 : 0)) { /* We did not call chmod so far, and either the mode and the ACL are separate or special bits are to be set which don't fit into ACLs. */ --- 370,377 ---- free (ace_entries); # endif ! if (!MODE_INSIDE_ACL ! || did_chmod <= ((mode & (S_ISUID | S_ISGID | S_ISVTX)) ? 1 : 0)) { /* We did not call chmod so far, and either the mode and the ACL are separate or special bits are to be set which don't fit into ACLs. */ *** lib/set-mode-acl.c.orig 2008-06-08 16:49:30.000000000 +0200 --- lib/set-mode-acl.c 2008-06-08 16:45:52.000000000 +0200 *************** *** 305,311 **** } } ! if (mode & (S_ISUID | S_ISGID | S_ISVTX)) { /* We did not call chmod so far, so the special bits have not yet been set. */ --- 305,311 ---- } } ! if (!MODE_INSIDE_ACL || (mode & (S_ISUID | S_ISGID | S_ISVTX))) { /* We did not call chmod so far, so the special bits have not yet been set. */