commit bac119a56eb286846ac5e7e046c31e7aa5844431 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sat Apr 25 10:49:42 2015 +0300 Improve doc string of 'insert-buffer-substring' * src/editfns.c (Finsert_buffer_substring): Doc fix. (Bug#20421) diff --git a/src/editfns.c b/src/editfns.c index 7d3e462..dead48c 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2728,7 +2728,15 @@ DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_subst doc: /* Insert before point a substring of the contents of BUFFER. BUFFER may be a buffer or a buffer name. Arguments START and END are character positions specifying the substring. -They default to the values of (point-min) and (point-max) in BUFFER. */) +They default to the values of (point-min) and (point-max) in BUFFER. + +Point and before-insertion markers move forward to end up after the +inserted text. +Any other markers at the point of insertion remain before the text. + +If the current buffer is multibyte and BUFFER is unibyte, or vice +versa, strings are converted from unibyte to multibyte or vice versa +using `string-make-multibyte' or `string-make-unibyte', which see. */) (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) { register EMACS_INT b, e, temp; commit 474519c96d7d819439ffac08cf270a2247eabf98 Author: Eli Zaretskii Date: Sat Apr 25 10:29:40 2015 +0300 MS-Windows followup for the recent gnulib update * nt/gnulib.mk (libgnu_a_SOURCES): Replace file-has-acl.c with acl-internal.c. diff --git a/nt/gnulib.mk b/nt/gnulib.mk index 4be3c2c..26a9ea9 100644 --- a/nt/gnulib.mk +++ b/nt/gnulib.mk @@ -523,7 +523,7 @@ EXTRA_libgnu_a_SOURCES += putenv.c ## begin gnulib module qacl -libgnu_a_SOURCES += acl-errno-valid.c file-has-acl.c qcopy-acl.c +libgnu_a_SOURCES += acl-errno-valid.c acl-internal.c qcopy-acl.c EXTRA_DIST += acl-internal.h acl.h acl_entries.c commit 2f5da6d45af2910d92c80bdd80d9895c3fa9f4cb Author: Paul Eggert Date: Fri Apr 24 23:19:36 2015 -0700 Spelling fixes diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 999e857..e45d79a 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -2486,7 +2486,7 @@ of these dependencies, similar to the list returned by "new" "available")))))))) (defvar package-menu--hide-obsolete t - "Whether avaiable obsolete packages should be hidden. + "Whether available obsolete packages should be hidden. Can be toggled with \\ \\[package-menu-hide-obsolete]. Installed obsolete packages are always displayed.") diff --git a/src/textprop.c b/src/textprop.c index f50ef08..0a591d0 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -737,7 +737,7 @@ DEFUN ("previous-char-property-change", Fprevious_char_property_change, Scans characters backward in the current buffer from POSITION till it finds a change in some text property, or the beginning or end of an overlay, and returns the position of that. -If none is found, and LIMIT is nil or imitted, the function +If none is found, and LIMIT is nil or omitted, the function returns (point-min). If the optional second argument LIMIT is non-nil, the function doesn't commit 27e6afeb6fe1f0b9f083fdfeacf6d69c6936a34a Author: Paul Eggert Date: Fri Apr 24 22:39:47 2015 -0700 Merge from gnulib This incorporates: 2015-04-24 file-has-acl: new module, split from acl 2015-04-24 manywarnings: add GCC 5.1 warnings 2015-04-21 lstat: fix cross-compilation 'ln -s' problem 2015-04-15 qacl: Simplify HP-UX acl_nontrivial check 2015-04-15 acl: On Linux, check for acls without libacl 2015-04-14 tempname: avoid unused parameter warnings (trivial) * lib/acl-internal.c: New file, from gnulib. * lib/file-has-acl.c: Remove; no longer imported from gnulib. * lib/acl-internal.h, lib/gnulib.mk, lib/qcopy-acl.c, lib/tempname.c: * m4/acl.m4, m4/gnulib-comp.m4, m4/lstat.m4, m4/manywarnings.m4: Update from gnulib. diff --git a/lib/acl-internal.c b/lib/acl-internal.c new file mode 100644 index 0000000..d9bd446 --- /dev/null +++ b/lib/acl-internal.c @@ -0,0 +1,469 @@ +/* Test whether a file has a nontrivial access control list. + + Copyright (C) 2002-2003, 2005-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */ + +#include + +#include "acl.h" + +#include "acl-internal.h" + +#if USE_ACL && HAVE_ACL_GET_FILE + +# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ + +/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. + Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial. */ +int +acl_extended_nontrivial (acl_t acl) +{ + /* acl is non-trivial if it is non-empty. */ + return (acl_entries (acl) > 0); +} + +# else /* Linux, FreeBSD, IRIX, Tru64 */ + +/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. + Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. + Return -1 and set errno upon failure to determine it. */ +int +acl_access_nontrivial (acl_t acl) +{ + /* acl is non-trivial if it has some entries other than for "user::", + "group::", and "other::". Normally these three should be present + at least, allowing us to write + return (3 < acl_entries (acl)); + but the following code is more robust. */ +# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */ + + acl_entry_t ace; + int got_one; + + for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); + got_one > 0; + got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) + { + acl_tag_t tag; + if (acl_get_tag_type (ace, &tag) < 0) + return -1; + if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) + return 1; + } + return got_one; + +# elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */ + /* Don't use acl_get_entry: it is undocumented. */ + + int count = acl->acl_cnt; + int i; + + for (i = 0; i < count; i++) + { + acl_entry_t ace = &acl->acl_entry[i]; + acl_tag_t tag = ace->ae_tag; + + if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ + || tag == ACL_OTHER_OBJ)) + return 1; + } + return 0; + +# elif HAVE_ACL_FREE_TEXT /* Tru64 */ + /* Don't use acl_get_entry: it takes only one argument and does not work. */ + + int count = acl->acl_num; + acl_entry_t ace; + + for (ace = acl->acl_first; count > 0; ace = ace->next, count--) + { + acl_tag_t tag; + acl_perm_t perm; + + tag = ace->entry->acl_type; + if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) + return 1; + + perm = ace->entry->acl_perm; + /* On Tru64, perm can also contain non-standard bits such as + PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */ + if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0) + return 1; + } + return 0; + +# else + + errno = ENOSYS; + return -1; +# endif +} + +# endif + +#elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ + +/* Test an ACL retrieved with GETACL. + Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_nontrivial (int count, aclent_t *entries) +{ + int i; + + for (i = 0; i < count; i++) + { + aclent_t *ace = &entries[i]; + + /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). + If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). + We don't need to check ace->a_id in these cases. */ + if (!(ace->a_type == USER_OBJ + || ace->a_type == GROUP_OBJ + || ace->a_type == OTHER_OBJ + /* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry + sometimes. */ + || ace->a_type == CLASS_OBJ)) + return 1; + } + return 0; +} + +# ifdef ACE_GETACL + +/* A shortcut for a bitmask. */ +# define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA) + +/* Test an ACL retrieved with ACE_GETACL. + Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_ace_nontrivial (int count, ace_t *entries) +{ + int i; + + /* The flags in the ace_t structure changed in a binary incompatible way + when ACL_NO_TRIVIAL etc. were introduced in version 1.15. + How to distinguish the two conventions at runtime? + In the old convention, usually three ACEs have a_flags = ACE_OWNER / + ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new + convention, these values are not used. */ + int old_convention = 0; + + for (i = 0; i < count; i++) + if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER)) + { + old_convention = 1; + break; + } + + if (old_convention) + /* Running on Solaris 10. */ + for (i = 0; i < count; i++) + { + ace_t *ace = &entries[i]; + + /* Note: + If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat(). + If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat(). + We don't need to check ace->a_who in these cases. */ + if (!(ace->a_type == OLD_ALLOW + && (ace->a_flags == OLD_ACE_OWNER + || ace->a_flags == OLD_ACE_GROUP + || ace->a_flags == OLD_ACE_OTHER))) + return 1; + } + else + { + /* Running on Solaris 10 (newer version) or Solaris 11. */ + unsigned int access_masks[6] = + { + 0, /* owner@ deny */ + 0, /* owner@ allow */ + 0, /* group@ deny */ + 0, /* group@ allow */ + 0, /* everyone@ deny */ + 0 /* everyone@ allow */ + }; + + for (i = 0; i < count; i++) + { + ace_t *ace = &entries[i]; + unsigned int index1; + unsigned int index2; + + if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE) + index1 = 1; + else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE) + index1 = 0; + else + return 1; + + if (ace->a_flags == NEW_ACE_OWNER) + index2 = 0; + else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP)) + index2 = 2; + else if (ace->a_flags == NEW_ACE_EVERYONE) + index2 = 4; + else + return 1; + + access_masks[index1 + index2] |= ace->a_access_mask; + } + + /* The same bit shouldn't be both allowed and denied. */ + if (access_masks[0] & access_masks[1]) + return 1; + if (access_masks[2] & access_masks[3]) + return 1; + if (access_masks[4] & access_masks[5]) + return 1; + + /* Check minimum masks. */ + if ((NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER) + & ~ access_masks[1]) + return 1; + access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER); + if ((NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE) + & ~ access_masks[5]) + return 1; + access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE); + + /* Check the allowed or denied bits. */ + switch ((access_masks[0] | access_masks[1]) + & ~(NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE)) + { + case 0: + case NEW_ACE_READ_DATA: + case NEW_ACE_WRITEA_DATA: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: + case NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + break; + default: + return 1; + } + switch ((access_masks[2] | access_masks[3]) + & ~(NEW_ACE_READ_NAMED_ATTRS + | NEW_ACE_READ_ATTRIBUTES + | NEW_ACE_READ_ACL + | NEW_ACE_SYNCHRONIZE)) + { + case 0: + case NEW_ACE_READ_DATA: + case NEW_ACE_WRITEA_DATA: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: + case NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + break; + default: + return 1; + } + switch ((access_masks[4] | access_masks[5]) + & ~(NEW_ACE_WRITE_NAMED_ATTRS + | NEW_ACE_WRITE_ATTRIBUTES + | NEW_ACE_WRITE_ACL + | NEW_ACE_WRITE_OWNER)) + { + case 0: + case NEW_ACE_READ_DATA: + case NEW_ACE_WRITEA_DATA: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: + case NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: + break; + default: + return 1; + } + + /* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are + either both allowed or both denied. */ + if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0) + != ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0)) + return 1; + } + + return 0; +} + +# endif + +#elif USE_ACL && HAVE_GETACL /* HP-UX */ + +/* Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_nontrivial (int count, struct acl_entry *entries) +{ + int i; + + if (count > 3) + return 1; + + for (i = 0; i < count; i++) + { + struct acl_entry *ace = &entries[i]; + + if (ace->uid != ACL_NSUSER && ace->gid != ACL_NSGROUP) + return 1; + } + return 0; +} + +# if HAVE_ACLV_H /* HP-UX >= 11.11 */ + +/* Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +aclv_nontrivial (int count, struct acl *entries) +{ + int i; + + for (i = 0; i < count; i++) + { + struct acl *ace = &entries[i]; + + /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). + If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). + We don't need to check ace->a_id in these cases. */ + if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */ + || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */ + || ace->a_type == CLASS_OBJ + || ace->a_type == OTHER_OBJ)) + return 1; + } + return 0; +} + +# endif + +#elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */ + +/* Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_nontrivial (struct acl *a) +{ + /* The normal way to iterate through an ACL is like this: + struct acl_entry *ace; + for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace)) + { + struct ace_id *aei; + switch (ace->ace_type) + { + case ACC_PERMIT: + case ACC_DENY: + case ACC_SPECIFY: + ...; + } + for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei)) + ... + } + */ + return (acl_last (a) != a->acl_ext ? 1 : 0); +} + +# if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */ + +/* Return 1 if the given ACL is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_nfs4_nontrivial (nfs4_acl_int_t *a) +{ +# if 1 /* let's try this first */ + return (a->aclEntryN > 0 ? 1 : 0); +# else + int count = a->aclEntryN; + int i; + + for (i = 0; i < count; i++) + { + nfs4_ace_int_t *ace = &a->aclEntry[i]; + + if (!((ace->flags & ACE4_ID_SPECIAL) != 0 + && (ace->aceWho.special_whoid == ACE4_WHO_OWNER + || ace->aceWho.special_whoid == ACE4_WHO_GROUP + || ace->aceWho.special_whoid == ACE4_WHO_EVERYONE) + && ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE + && ace->aceFlags == 0 + && (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY + | ACE4_WRITE_DATA | ACE4_ADD_FILE + | ACE4_EXECUTE)) == 0)) + return 1; + } + return 0; +# endif +} + +# endif + +#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */ + +/* Test an ACL retrieved with ACL_GET. + Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. + Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ +int +acl_nontrivial (int count, struct acl *entries) +{ + int i; + + for (i = 0; i < count; i++) + { + struct acl *ace = &entries[i]; + + /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). + If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). + We don't need to check ace->a_id in these cases. */ + if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */ + || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */ + || ace->a_type == CLASS_OBJ + || ace->a_type == OTHER_OBJ)) + return 1; + } + return 0; +} + +#endif diff --git a/lib/acl-internal.h b/lib/acl-internal.h index 243ca32..9b9fae2 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -220,7 +220,7 @@ extern int acl_ace_nontrivial (int count, ace_t *entries) _GL_ATTRIBUTE_PURE; /* 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, struct acl_entry *entries, struct stat *sb); +extern int acl_nontrivial (int count, struct acl_entry *entries); # if HAVE_ACLV_H /* HP-UX >= 11.11 */ diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c deleted file mode 100644 index 2ef4e8b..0000000 --- a/lib/file-has-acl.c +++ /dev/null @@ -1,919 +0,0 @@ -/* Test whether a file has a nontrivial access control list. - - Copyright (C) 2002-2003, 2005-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */ - -/* Without this pragma, gcc 4.7.0 20120126 may suggest that the - file_has_acl function might be candidate for attribute 'const' */ -#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ -# pragma GCC diagnostic ignored "-Wsuggest-attribute=const" -#endif - -#include - -#include "acl.h" - -#include "acl-internal.h" - - -#if USE_ACL && HAVE_ACL_GET_FILE - -# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - -/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED. - Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial. */ -int -acl_extended_nontrivial (acl_t acl) -{ - /* acl is non-trivial if it is non-empty. */ - return (acl_entries (acl) > 0); -} - -# else /* Linux, FreeBSD, IRIX, Tru64 */ - -/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. - Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. - Return -1 and set errno upon failure to determine it. */ -int -acl_access_nontrivial (acl_t acl) -{ - /* acl is non-trivial if it has some entries other than for "user::", - "group::", and "other::". Normally these three should be present - at least, allowing us to write - return (3 < acl_entries (acl)); - but the following code is more robust. */ -# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */ - - acl_entry_t ace; - int got_one; - - for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace); - got_one > 0; - got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) - { - acl_tag_t tag; - if (acl_get_tag_type (ace, &tag) < 0) - return -1; - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) - return 1; - } - return got_one; - -# elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */ - /* Don't use acl_get_entry: it is undocumented. */ - - int count = acl->acl_cnt; - int i; - - for (i = 0; i < count; i++) - { - acl_entry_t ace = &acl->acl_entry[i]; - acl_tag_t tag = ace->ae_tag; - - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ - || tag == ACL_OTHER_OBJ)) - return 1; - } - return 0; - -# elif HAVE_ACL_FREE_TEXT /* Tru64 */ - /* Don't use acl_get_entry: it takes only one argument and does not work. */ - - int count = acl->acl_num; - acl_entry_t ace; - - for (ace = acl->acl_first; count > 0; ace = ace->next, count--) - { - acl_tag_t tag; - acl_perm_t perm; - - tag = ace->entry->acl_type; - if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER)) - return 1; - - perm = ace->entry->acl_perm; - /* On Tru64, perm can also contain non-standard bits such as - PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */ - if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0) - return 1; - } - return 0; - -# else - - errno = ENOSYS; - return -1; -# endif -} - -# endif - - -#elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ - -/* Test an ACL retrieved with GETACL. - Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_nontrivial (int count, aclent_t *entries) -{ - int i; - - for (i = 0; i < count; i++) - { - aclent_t *ace = &entries[i]; - - /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). - If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). - We don't need to check ace->a_id in these cases. */ - if (!(ace->a_type == USER_OBJ - || ace->a_type == GROUP_OBJ - || ace->a_type == OTHER_OBJ - /* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry - sometimes. */ - || ace->a_type == CLASS_OBJ)) - return 1; - } - return 0; -} - -# ifdef ACE_GETACL - -/* A shortcut for a bitmask. */ -# define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA) - -/* Test an ACL retrieved with ACE_GETACL. - Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_ace_nontrivial (int count, ace_t *entries) -{ - int i; - - /* The flags in the ace_t structure changed in a binary incompatible way - when ACL_NO_TRIVIAL etc. were introduced in version 1.15. - How to distinguish the two conventions at runtime? - In the old convention, usually three ACEs have a_flags = ACE_OWNER / - ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new - convention, these values are not used. */ - int old_convention = 0; - - for (i = 0; i < count; i++) - if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER)) - { - old_convention = 1; - break; - } - - if (old_convention) - /* Running on Solaris 10. */ - for (i = 0; i < count; i++) - { - ace_t *ace = &entries[i]; - - /* Note: - If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat(). - If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat(). - We don't need to check ace->a_who in these cases. */ - if (!(ace->a_type == OLD_ALLOW - && (ace->a_flags == OLD_ACE_OWNER - || ace->a_flags == OLD_ACE_GROUP - || ace->a_flags == OLD_ACE_OTHER))) - return 1; - } - else - { - /* Running on Solaris 10 (newer version) or Solaris 11. */ - unsigned int access_masks[6] = - { - 0, /* owner@ deny */ - 0, /* owner@ allow */ - 0, /* group@ deny */ - 0, /* group@ allow */ - 0, /* everyone@ deny */ - 0 /* everyone@ allow */ - }; - - for (i = 0; i < count; i++) - { - ace_t *ace = &entries[i]; - unsigned int index1; - unsigned int index2; - - if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE) - index1 = 1; - else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE) - index1 = 0; - else - return 1; - - if (ace->a_flags == NEW_ACE_OWNER) - index2 = 0; - else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP)) - index2 = 2; - else if (ace->a_flags == NEW_ACE_EVERYONE) - index2 = 4; - else - return 1; - - access_masks[index1 + index2] |= ace->a_access_mask; - } - - /* The same bit shouldn't be both allowed and denied. */ - if (access_masks[0] & access_masks[1]) - return 1; - if (access_masks[2] & access_masks[3]) - return 1; - if (access_masks[4] & access_masks[5]) - return 1; - - /* Check minimum masks. */ - if ((NEW_ACE_WRITE_NAMED_ATTRS - | NEW_ACE_WRITE_ATTRIBUTES - | NEW_ACE_WRITE_ACL - | NEW_ACE_WRITE_OWNER) - & ~ access_masks[1]) - return 1; - access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS - | NEW_ACE_WRITE_ATTRIBUTES - | NEW_ACE_WRITE_ACL - | NEW_ACE_WRITE_OWNER); - if ((NEW_ACE_READ_NAMED_ATTRS - | NEW_ACE_READ_ATTRIBUTES - | NEW_ACE_READ_ACL - | NEW_ACE_SYNCHRONIZE) - & ~ access_masks[5]) - return 1; - access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS - | NEW_ACE_READ_ATTRIBUTES - | NEW_ACE_READ_ACL - | NEW_ACE_SYNCHRONIZE); - - /* Check the allowed or denied bits. */ - switch ((access_masks[0] | access_masks[1]) - & ~(NEW_ACE_READ_NAMED_ATTRS - | NEW_ACE_READ_ATTRIBUTES - | NEW_ACE_READ_ACL - | NEW_ACE_SYNCHRONIZE)) - { - case 0: - case NEW_ACE_READ_DATA: - case NEW_ACE_WRITEA_DATA: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: - case NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - break; - default: - return 1; - } - switch ((access_masks[2] | access_masks[3]) - & ~(NEW_ACE_READ_NAMED_ATTRS - | NEW_ACE_READ_ATTRIBUTES - | NEW_ACE_READ_ACL - | NEW_ACE_SYNCHRONIZE)) - { - case 0: - case NEW_ACE_READ_DATA: - case NEW_ACE_WRITEA_DATA: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: - case NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - break; - default: - return 1; - } - switch ((access_masks[4] | access_masks[5]) - & ~(NEW_ACE_WRITE_NAMED_ATTRS - | NEW_ACE_WRITE_ATTRIBUTES - | NEW_ACE_WRITE_ACL - | NEW_ACE_WRITE_OWNER)) - { - case 0: - case NEW_ACE_READ_DATA: - case NEW_ACE_WRITEA_DATA: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA: - case NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE: - break; - default: - return 1; - } - - /* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are - either both allowed or both denied. */ - if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0) - != ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0)) - return 1; - if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0) - != ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0)) - return 1; - if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0) - != ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0)) - return 1; - } - - return 0; -} - -# endif - -#elif USE_ACL && HAVE_GETACL /* HP-UX */ - -/* Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb) -{ - int i; - - for (i = 0; i < count; i++) - { - struct acl_entry *ace = &entries[i]; - - if (!((ace->uid == sb->st_uid && ace->gid == ACL_NSGROUP) - || (ace->uid == ACL_NSUSER && ace->gid == sb->st_gid) - || (ace->uid == ACL_NSUSER && ace->gid == ACL_NSGROUP))) - return 1; - } - return 0; -} - -# if HAVE_ACLV_H /* HP-UX >= 11.11 */ - -/* Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -aclv_nontrivial (int count, struct acl *entries) -{ - int i; - - for (i = 0; i < count; i++) - { - struct acl *ace = &entries[i]; - - /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). - If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). - We don't need to check ace->a_id in these cases. */ - if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */ - || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */ - || ace->a_type == CLASS_OBJ - || ace->a_type == OTHER_OBJ)) - return 1; - } - return 0; -} - -# endif - -#elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */ - -/* Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_nontrivial (struct acl *a) -{ - /* The normal way to iterate through an ACL is like this: - struct acl_entry *ace; - for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace)) - { - struct ace_id *aei; - switch (ace->ace_type) - { - case ACC_PERMIT: - case ACC_DENY: - case ACC_SPECIFY: - ...; - } - for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei)) - ... - } - */ - return (acl_last (a) != a->acl_ext ? 1 : 0); -} - -# if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */ - -/* Return 1 if the given ACL is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_nfs4_nontrivial (nfs4_acl_int_t *a) -{ -# if 1 /* let's try this first */ - return (a->aclEntryN > 0 ? 1 : 0); -# else - int count = a->aclEntryN; - int i; - - for (i = 0; i < count; i++) - { - nfs4_ace_int_t *ace = &a->aclEntry[i]; - - if (!((ace->flags & ACE4_ID_SPECIAL) != 0 - && (ace->aceWho.special_whoid == ACE4_WHO_OWNER - || ace->aceWho.special_whoid == ACE4_WHO_GROUP - || ace->aceWho.special_whoid == ACE4_WHO_EVERYONE) - && ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE - && ace->aceFlags == 0 - && (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY - | ACE4_WRITE_DATA | ACE4_ADD_FILE - | ACE4_EXECUTE)) == 0)) - return 1; - } - return 0; -# endif -} - -# endif - -#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */ - -/* Test an ACL retrieved with ACL_GET. - Return 1 if the given ACL, consisting of COUNT entries, is non-trivial. - Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */ -int -acl_nontrivial (int count, struct acl *entries) -{ - int i; - - for (i = 0; i < count; i++) - { - struct acl *ace = &entries[i]; - - /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat(). - If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat(). - We don't need to check ace->a_id in these cases. */ - if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */ - || ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */ - || ace->a_type == CLASS_OBJ - || ace->a_type == OTHER_OBJ)) - return 1; - } - return 0; -} - -#endif - - -/* Return 1 if NAME has a nontrivial access control list, 0 if NAME - only has no or a base access control list, and -1 (setting errno) - on error. SB must be set to the stat buffer of NAME, obtained - through stat() or lstat(). */ - -int -file_has_acl (char const *name, struct stat const *sb) -{ -#if USE_ACL - if (! S_ISLNK (sb->st_mode)) - { -# if HAVE_ACL_GET_FILE - - /* POSIX 1003.1e (draft 17 -- abandoned) specific version. */ - /* Linux, FreeBSD, Mac OS X, IRIX, Tru64 */ - int ret; - - if (HAVE_ACL_EXTENDED_FILE) /* Linux */ - { - /* On Linux, acl_extended_file is an optimized function: It only - makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for - ACL_TYPE_DEFAULT. */ - ret = acl_extended_file (name); - } - else /* FreeBSD, Mac OS X, IRIX, Tru64 */ - { -# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ - /* On Mac OS X, acl_get_file (name, ACL_TYPE_ACCESS) - and acl_get_file (name, ACL_TYPE_DEFAULT) - always return NULL / EINVAL. There is no point in making - these two useless calls. The real ACL is retrieved through - acl_get_file (name, ACL_TYPE_EXTENDED). */ - acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED); - if (acl) - { - ret = acl_extended_nontrivial (acl); - acl_free (acl); - } - else - ret = -1; -# else /* FreeBSD, IRIX, Tru64 */ - acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS); - if (acl) - { - int saved_errno; - - ret = acl_access_nontrivial (acl); - saved_errno = errno; - acl_free (acl); - errno = saved_errno; -# if HAVE_ACL_FREE_TEXT /* Tru64 */ - /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always - returns NULL with errno not set. There is no point in - making this call. */ -# else /* FreeBSD, IRIX */ - /* On Linux, FreeBSD, IRIX, acl_get_file (name, ACL_TYPE_ACCESS) - and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory - either both succeed or both fail; it depends on the - file system. Therefore there is no point in making the second - call if the first one already failed. */ - if (ret == 0 && S_ISDIR (sb->st_mode)) - { - acl = acl_get_file (name, ACL_TYPE_DEFAULT); - if (acl) - { - ret = (0 < acl_entries (acl)); - acl_free (acl); - } - else - ret = -1; - } -# endif - } - else - ret = -1; -# endif - } - if (ret < 0) - return - acl_errno_valid (errno); - return ret; - -# elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */ - -# if defined ACL_NO_TRIVIAL - - /* Solaris 10 (newer version), which has additional API declared in - (acl_t) and implemented in libsec (acl_set, acl_trivial, - acl_fromtext, ...). */ - return acl_trivial (name); - -# else /* Solaris, Cygwin, general case */ - - /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions - of Unixware. The acl() call returns the access and default ACL both - at once. */ - { - /* Initially, try to read the entries into a stack-allocated buffer. - Use malloc if it does not fit. */ - enum - { - alloc_init = 4000 / sizeof (aclent_t), /* >= 3 */ - alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (aclent_t)) - }; - aclent_t buf[alloc_init]; - size_t alloc = alloc_init; - aclent_t *entries = buf; - aclent_t *malloced = NULL; - int count; - - for (;;) - { - count = acl (name, GETACL, alloc, entries); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ - free (malloced); - if (alloc > alloc_max / 2) - { - errno = ENOMEM; - return -1; - } - alloc = 2 * alloc; /* <= alloc_max */ - entries = malloced = - (aclent_t *) malloc (alloc * sizeof (aclent_t)); - if (entries == NULL) - { - errno = ENOMEM; - return -1; - } - continue; - } - break; - } - if (count < 0) - { - if (errno == ENOSYS || errno == ENOTSUP) - ; - else - { - int saved_errno = errno; - free (malloced); - errno = saved_errno; - return -1; - } - } - else if (count == 0) - ; - else - { - /* Don't use MIN_ACL_ENTRIES: It's set to 4 on Cygwin, but Cygwin - returns only 3 entries for files with no ACL. But this is safe: - If there are more than 4 entries, there cannot be only the - "user::", "group::", "other:", and "mask:" entries. */ - if (count > 4) - { - free (malloced); - return 1; - } - - if (acl_nontrivial (count, entries)) - { - free (malloced); - return 1; - } - } - free (malloced); - } - -# ifdef ACE_GETACL - /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4 - file systems (whereas the other ones are used in UFS file systems). */ - { - /* Initially, try to read the entries into a stack-allocated buffer. - Use malloc if it does not fit. */ - enum - { - alloc_init = 4000 / sizeof (ace_t), /* >= 3 */ - alloc_max = MIN (INT_MAX, SIZE_MAX / sizeof (ace_t)) - }; - ace_t buf[alloc_init]; - size_t alloc = alloc_init; - ace_t *entries = buf; - ace_t *malloced = NULL; - int count; - - for (;;) - { - count = acl (name, ACE_GETACL, alloc, entries); - if (count < 0 && errno == ENOSPC) - { - /* Increase the size of the buffer. */ - free (malloced); - if (alloc > alloc_max / 2) - { - errno = ENOMEM; - return -1; - } - alloc = 2 * alloc; /* <= alloc_max */ - entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t)); - if (entries == NULL) - { - errno = ENOMEM; - return -1; - } - continue; - } - break; - } - if (count < 0) - { - if (errno == ENOSYS || errno == EINVAL) - ; - else - { - int saved_errno = errno; - free (malloced); - errno = saved_errno; - return -1; - } - } - else if (count == 0) - ; - else - { - /* In the old (original Solaris 10) convention: - If there are more than 3 entries, there cannot be only the - ACE_OWNER, ACE_GROUP, ACE_OTHER entries. - In the newer Solaris 10 and Solaris 11 convention: - If there are more than 6 entries, there cannot be only the - ACE_OWNER, ACE_GROUP, ACE_EVERYONE entries, each once with - NEW_ACE_ACCESS_ALLOWED_ACE_TYPE and once with - NEW_ACE_ACCESS_DENIED_ACE_TYPE. */ - if (count > 6) - { - free (malloced); - return 1; - } - - if (acl_ace_nontrivial (count, entries)) - { - free (malloced); - return 1; - } - } - free (malloced); - } -# endif - - return 0; -# endif - -# elif HAVE_GETACL /* HP-UX */ - - { - struct acl_entry entries[NACLENTRIES]; - int count; - - count = getacl (name, NACLENTRIES, entries); - - if (count < 0) - { - /* ENOSYS is seen on newer HP-UX versions. - EOPNOTSUPP is typically seen on NFS mounts. - ENOTSUP was seen on Quantum StorNext file systems (cvfs). */ - if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP) - ; - else - return -1; - } - else if (count == 0) - return 0; - else /* count > 0 */ - { - if (count > NACLENTRIES) - /* If NACLENTRIES cannot be trusted, use dynamic memory - allocation. */ - abort (); - - /* If there are more than 3 entries, there cannot be only the - (uid,%), (%,gid), (%,%) entries. */ - if (count > 3) - return 1; - - { - struct stat statbuf; - - if (stat (name, &statbuf) < 0) - return -1; - - return acl_nontrivial (count, entries, &statbuf); - } - } - } - -# if HAVE_ACLV_H /* HP-UX >= 11.11 */ - - { - struct acl entries[NACLVENTRIES]; - int count; - - count = acl ((char *) name, ACL_GET, NACLVENTRIES, entries); - - if (count < 0) - { - /* EOPNOTSUPP is seen on NFS in HP-UX 11.11, 11.23. - EINVAL is seen on NFS in HP-UX 11.31. */ - if (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL) - ; - else - return -1; - } - else if (count == 0) - return 0; - else /* count > 0 */ - { - if (count > NACLVENTRIES) - /* If NACLVENTRIES cannot be trusted, use dynamic memory - allocation. */ - abort (); - - /* If there are more than 4 entries, there cannot be only the - four base ACL entries. */ - if (count > 4) - return 1; - - return aclv_nontrivial (count, entries); - } - } - -# endif - -# elif HAVE_ACLX_GET && defined ACL_AIX_WIP /* AIX */ - - acl_type_t type; - char aclbuf[1024]; - void *acl = aclbuf; - size_t aclsize = sizeof (aclbuf); - mode_t mode; - - for (;;) - { - /* The docs say that type being 0 is equivalent to ACL_ANY, but it - is not true, in AIX 5.3. */ - type.u64 = ACL_ANY; - if (aclx_get (name, 0, &type, aclbuf, &aclsize, &mode) >= 0) - break; - if (errno == ENOSYS) - return 0; - if (errno != ENOSPC) - { - if (acl != aclbuf) - { - int saved_errno = errno; - free (acl); - errno = saved_errno; - } - return -1; - } - aclsize = 2 * aclsize; - if (acl != aclbuf) - free (acl); - acl = malloc (aclsize); - if (acl == NULL) - { - errno = ENOMEM; - return -1; - } - } - - if (type.u64 == ACL_AIXC) - { - int result = acl_nontrivial ((struct acl *) acl); - if (acl != aclbuf) - free (acl); - return result; - } - else if (type.u64 == ACL_NFS4) - { - int result = acl_nfs4_nontrivial ((nfs4_acl_int_t *) acl); - if (acl != aclbuf) - free (acl); - return result; - } - else - { - /* A newer type of ACL has been introduced in the system. - We should better support it. */ - if (acl != aclbuf) - free (acl); - errno = EINVAL; - return -1; - } - -# elif HAVE_STATACL /* older AIX */ - - union { struct acl a; char room[4096]; } u; - - if (statacl (name, STX_NORMAL, &u.a, sizeof (u)) < 0) - return -1; - - return acl_nontrivial (&u.a); - -# elif HAVE_ACLSORT /* NonStop Kernel */ - - { - struct acl entries[NACLENTRIES]; - int count; - - count = acl ((char *) name, ACL_GET, NACLENTRIES, entries); - - if (count < 0) - { - if (errno == ENOSYS || errno == ENOTSUP) - ; - else - return -1; - } - else if (count == 0) - return 0; - else /* count > 0 */ - { - if (count > NACLENTRIES) - /* If NACLENTRIES cannot be trusted, use dynamic memory - allocation. */ - abort (); - - /* If there are more than 4 entries, there cannot be only the - four base ACL entries. */ - if (count > 4) - return 1; - - return acl_nontrivial (count, entries); - } - } - -# endif - } -#endif - - return 0; -} diff --git a/lib/gnulib.mk b/lib/gnulib.mk index 273b018..bec0d3b 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -698,7 +698,7 @@ EXTRA_libgnu_a_SOURCES += putenv.c ## begin gnulib module qacl -libgnu_a_SOURCES += acl-errno-valid.c file-has-acl.c qcopy-acl.c qset-acl.c +libgnu_a_SOURCES += acl-errno-valid.c acl-internal.c qcopy-acl.c qset-acl.c EXTRA_DIST += acl-internal.h acl.h acl_entries.c diff --git a/lib/qcopy-acl.c b/lib/qcopy-acl.c index aac76a1..bc258ba 100644 --- a/lib/qcopy-acl.c +++ b/lib/qcopy-acl.c @@ -437,20 +437,9 @@ qcopy_acl (const char *src_name, int source_desc, const char *dst_name, if (ret < 0 && saved_errno == 0) { saved_errno = errno; - if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP) - { - struct stat source_statbuf; - - if ((source_desc != -1 - ? fstat (source_desc, &source_statbuf) - : stat (src_name, &source_statbuf)) == 0) - { - if (!acl_nontrivial (count, entries, &source_statbuf)) - saved_errno = 0; - } - else - saved_errno = errno; - } + if (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP + && !acl_nontrivial (count, entries)) + saved_errno = 0; } else did_chmod = 1; diff --git a/lib/tempname.c b/lib/tempname.c index 8e6d26c..69c572f 100644 --- a/lib/tempname.c +++ b/lib/tempname.c @@ -269,13 +269,13 @@ try_file (char *tmpl, void *flags) } static int -try_dir (char *tmpl, void *flags) +try_dir (char *tmpl, void *flags _GL_UNUSED) { return __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); } static int -try_nocreate (char *tmpl, void *flags) +try_nocreate (char *tmpl, void *flags _GL_UNUSED) { struct_stat64 st; diff --git a/m4/acl.m4 b/m4/acl.m4 index c77f0ed..186353c 100644 --- a/m4/acl.m4 +++ b/m4/acl.m4 @@ -1,5 +1,5 @@ # acl.m4 - check for access control list (ACL) primitives -# serial 17 +# serial 18 # Copyright (C) 2002, 2004-2015 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation @@ -8,23 +8,29 @@ # Written by Paul Eggert and Jim Meyering. -AC_DEFUN([gl_FUNC_ACL], +AC_DEFUN([gl_FUNC_ACL_ARG], [ + gl_need_lib_has_acl= AC_ARG_ENABLE([acl], AS_HELP_STRING([--disable-acl], [do not support ACLs]), , [enable_acl=auto]) +]) + +AC_DEFUN([gl_FUNC_ACL], +[ + AC_REQUIRE([gl_FUNC_ACL_ARG]) AC_CHECK_FUNCS_ONCE([fchmod]) LIB_ACL= use_acl=0 - if test "x$enable_acl" != "xno"; then + if test "$enable_acl" != no; then dnl On all platforms, the ACL related API is declared in . AC_CHECK_HEADERS([sys/acl.h]) if test $ac_cv_header_sys_acl_h = yes; then ac_save_LIBS=$LIBS - dnl Test for POSIX-draft-like API (Linux, FreeBSD, Mac OS X, IRIX, Tru64). - dnl -lacl is needed on Linux, -lpacl is needed on OSF/1. + dnl Test for POSIX-draft-like API (GNU/Linux, FreeBSD, Mac OS X, + dnl IRIX, Tru64). -lacl is needed on GNU/Linux, -lpacl on OSF/1. if test $use_acl = 0; then AC_SEARCH_LIBS([acl_get_file], [acl pacl], [if test "$ac_cv_search_acl_get_file" != "none required"; then @@ -40,7 +46,7 @@ AC_DEFUN([gl_FUNC_ACL], # If the acl_get_file bug is detected, don't enable the ACL support. gl_ACL_GET_FILE([use_acl=1], []) if test $use_acl = 1; then - dnl On Linux, additional API is declared in . + dnl On GNU/Linux, an additional API is declared in . AC_CHECK_HEADERS([acl/libacl.h]) AC_REPLACE_FUNCS([acl_entries]) AC_CACHE_CHECK([for ACL_FIRST_ENTRY], @@ -124,13 +130,15 @@ int type = ACL_TYPE_EXTENDED;]])], LIBS=$ac_save_LIBS fi - if test "x$enable_acl$use_acl" = "xyes0"; then + + if test "$enable_acl$use_acl" = yes0; then AC_MSG_ERROR([ACLs enabled but support not detected]) - elif test "x$enable_acl$use_acl" = "xauto0"; then + elif test "$enable_acl$use_acl" = auto0; then AC_MSG_WARN([libacl development library was not found or not usable.]) AC_MSG_WARN([AC_PACKAGE_NAME will be built without ACL support.]) fi fi + test $gl_need_lib_has_acl && LIB_HAS_ACL=$LIB_ACL AC_SUBST([LIB_ACL]) AC_DEFINE_UNQUOTED([USE_ACL], [$use_acl], [Define to nonzero if you want access control list support.]) @@ -139,7 +147,7 @@ int type = ACL_TYPE_EXTENDED;]])], ]) # gl_ACL_GET_FILE(IF-WORKS, IF-NOT) -# ------------------------------------- +# --------------------------------- # If 'acl_get_file' works (does not have a particular bug), # run IF-WORKS, otherwise, IF-NOT. # When building natively, test for a Darwin 8.7.0 bug, whereby acl_get_file @@ -166,3 +174,24 @@ AC_DEFUN([gl_ACL_GET_FILE], fi])]) AS_IF([test "$gl_cv_func_working_acl_get_file" != no], [$1], [$2]) ]) + +# On GNU/Linux, testing if a file has an acl can be done with the getxattr +# syscall which doesn't require linking against additional libraries. +AC_DEFUN([gl_FILE_HAS_ACL], +[ + AC_REQUIRE([gl_FUNC_ACL_ARG]) + if test "$enable_acl" != no; then + AC_CHECK_HEADERS([linux/xattr.h], + [AC_CHECK_HEADERS([sys/xattr.h], + [AC_CHECK_FUNCS([getxattr])])]) + fi + if test "$ac_cv_header_sys_xattr_h,$ac_cv_header_linux_xattr_h,$ac_cv_func_getxattr" = yes,yes,yes; then + LIB_HAS_ACL= + else + dnl Set gl_need_lib_has_acl to a nonempty value, so that any + dnl later gl_FUNC_ACL call will set LIB_HAS_ACL=$LIB_ACL. + gl_need_lib_has_acl=1 + LIB_HAS_ACL=$LIB_ACL + fi + AC_SUBST([LIB_HAS_ACL]) +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index f32a4dd..06636cf 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -818,6 +818,7 @@ AC_DEFUN([gl_FILE_LIST], [ build-aux/snippet/warn-on-use.h build-aux/update-copyright lib/acl-errno-valid.c + lib/acl-internal.c lib/acl-internal.h lib/acl.h lib/acl_entries.c @@ -856,7 +857,6 @@ AC_DEFUN([gl_FILE_LIST], [ lib/fcntl.in.h lib/fdatasync.c lib/fdopendir.c - lib/file-has-acl.c lib/filemode.c lib/filemode.h lib/fpending.c diff --git a/m4/lstat.m4 b/m4/lstat.m4 index f6c7dd1..adf752c 100644 --- a/m4/lstat.m4 +++ b/m4/lstat.m4 @@ -1,4 +1,4 @@ -# serial 26 +# serial 27 # Copyright (C) 1997-2001, 2003-2015 Free Software Foundation, Inc. # @@ -37,30 +37,28 @@ AC_DEFUN([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK], [gl_cv_func_lstat_dereferences_slashed_symlink], [rm -f conftest.sym conftest.file echo >conftest.file - if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then - AC_RUN_IFELSE( - [AC_LANG_PROGRAM( - [AC_INCLUDES_DEFAULT], - [[struct stat sbuf; - /* Linux will dereference the symlink and fail, as required by - POSIX. That is better in the sense that it means we will not - have to compile and use the lstat wrapper. */ - return lstat ("conftest.sym/", &sbuf) == 0; - ]])], - [gl_cv_func_lstat_dereferences_slashed_symlink=yes], - [gl_cv_func_lstat_dereferences_slashed_symlink=no], - [case "$host_os" in - # Guess yes on glibc systems. - *-gnu*) gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; - # If we don't know, assume the worst. - *) gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;; - esac - ]) - else - # If the 'ln -s' command failed, then we probably don't even - # have an lstat function. - gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" - fi + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [AC_INCLUDES_DEFAULT], + [[struct stat sbuf; + if (symlink ("conftest.file", "conftest.sym") != 0) + return 1; + /* Linux will dereference the symlink and fail, as required by + POSIX. That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ]])], + [gl_cv_func_lstat_dereferences_slashed_symlink=yes], + [gl_cv_func_lstat_dereferences_slashed_symlink=no], + [case "$host_os" in + *-gnu*) + # Guess yes on glibc systems. + gl_cv_func_lstat_dereferences_slashed_symlink="guessing yes" ;; + *) + # If we don't know, assume the worst. + gl_cv_func_lstat_dereferences_slashed_symlink="guessing no" ;; + esac + ]) rm -f conftest.sym conftest.file ]) case "$gl_cv_func_lstat_dereferences_slashed_symlink" in diff --git a/m4/manywarnings.m4 b/m4/manywarnings.m4 index 44da98e..b4e38d9 100644 --- a/m4/manywarnings.m4 +++ b/m4/manywarnings.m4 @@ -108,12 +108,13 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Waddress \ -Waggressive-loop-optimizations \ -Wall \ - -Warray-bounds \ -Wattributes \ -Wbad-function-cast \ + -Wbool-compare \ -Wbuiltin-macro-redefined \ -Wcast-align \ -Wchar-subscripts \ + -Wchkp \ -Wclobbered \ -Wcomment \ -Wcomments \ @@ -122,7 +123,10 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wdate-time \ -Wdeprecated \ -Wdeprecated-declarations \ + -Wdesignated-init \ -Wdisabled-optimization \ + -Wdiscarded-array-qualifiers \ + -Wdiscarded-qualifiers \ -Wdiv-by-zero \ -Wdouble-promotion \ -Wempty-body \ @@ -133,6 +137,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wformat-extra-args \ -Wformat-nonliteral \ -Wformat-security \ + -Wformat-signedness \ -Wformat-y2k \ -Wformat-zero-length \ -Wfree-nonheap-object \ @@ -140,15 +145,19 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wimplicit \ -Wimplicit-function-declaration \ -Wimplicit-int \ + -Wincompatible-pointer-types \ -Winit-self \ -Winline \ + -Wint-conversion \ -Wint-to-pointer-cast \ -Winvalid-memory-model \ -Winvalid-pch \ -Wjump-misses-init \ + -Wlogical-not-parentheses \ -Wlogical-op \ -Wmain \ -Wmaybe-uninitialized \ + -Wmemset-transposed-args \ -Wmissing-braces \ -Wmissing-declarations \ -Wmissing-field-initializers \ @@ -159,6 +168,7 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wnarrowing \ -Wnested-externs \ -Wnonnull \ + -Wodr \ -Wold-style-declaration \ -Wold-style-definition \ -Wopenmp-simd \ @@ -176,6 +186,9 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wreturn-type \ -Wsequence-point \ -Wshadow \ + -Wshift-count-negative \ + -Wshift-count-overflow \ + -Wsizeof-array-argument \ -Wsizeof-pointer-memaccess \ -Wstack-protector \ -Wstrict-aliasing \ @@ -185,7 +198,10 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], -Wsuggest-attribute=format \ -Wsuggest-attribute=noreturn \ -Wsuggest-attribute=pure \ + -Wsuggest-final-methods \ + -Wsuggest-final-types \ -Wswitch \ + -Wswitch-bool \ -Wswitch-default \ -Wsync-nand \ -Wsystem-headers \ @@ -217,8 +233,9 @@ AC_DEFUN([gl_MANYWARN_ALL_GCC], gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item" done - # gcc --help=warnings outputs an unusual form for this option; list - # it here so that the above 'comm' command doesn't report a false match. + # gcc --help=warnings outputs an unusual form for these options; list + # them here so that the above 'comm' command doesn't report a false match. + gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2" gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc" # These are needed for older GCC versions. commit 52ba851db188de47b303120df00c77e3aad7e542 Author: Paul Eggert Date: Fri Apr 24 22:37:11 2015 -0700 Port --enable-gcc-warnings to GCC 5.1 x86-64 * lib-src/ebrowse.c (dump_sym): * lib-src/hexl.c (main): * src/ccl.c (ccl_driver): * src/character.c (string_escape_byte8): * src/dbusbind.c (xd_retrieve_arg, xd_add_watch): * src/gnutls.c (Fgnutls_boot): * src/gtkutil.c (xg_check_special_colors): * src/image.c (x_build_heuristic_mask): * src/print.c (safe_debug_print, print_object): * src/term.c (produce_glyphless_glyph): * src/xdisp.c (get_next_display_element) (produce_glyphless_glyph): * src/xterm.c (x_draw_glyphless_glyph_string_foreground): Don't use a signed format to print an unsigned integer, or vice versa. GCC 5.1's new -Wformat-signedness option warns about this. * src/image.c (png_load_body, jpeg_load_body): Silence a bogus setjump diagnostic from GCC 5.1 (GCC bug 54561). diff --git a/lib-src/ebrowse.c b/lib-src/ebrowse.c index d16c9ae..5c1e9d9 100644 --- a/lib-src/ebrowse.c +++ b/lib-src/ebrowse.c @@ -1241,7 +1241,7 @@ dump_sym (FILE *fp, struct sym *root) putstr (NULL, fp); /* Print flags. */ - fprintf (fp, "%u", root->flags); + fprintf (fp, "%d", root->flags); putstr (root->filename, fp); putstr (root->regexp, fp); fprintf (fp, "%u", (unsigned) root->pos); diff --git a/lib-src/hexl.c b/lib-src/hexl.c index 490f727..ac493c2 100644 --- a/lib-src/hexl.c +++ b/lib-src/hexl.c @@ -216,7 +216,7 @@ main (int argc, char **argv) else { if (!i) - printf ("%08lx: ", address); + printf ("%08lx: ", address + 0ul); if (iso_flag) string[i+1] = @@ -224,7 +224,7 @@ main (int argc, char **argv) else string[i+1] = (c < 0x20 || c >= 0x7F) ? '.' : c; - printf ("%02x", c); + printf ("%02x", c + 0u); } if ((i&group_by) == group_by) diff --git a/src/ccl.c b/src/ccl.c index 053544c..88307a3 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -1713,7 +1713,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size case CCL_STAT_INVALID_CMD: msglen = sprintf (msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", - code & 0x1F, code, this_ic); + code & 0x1Fu, code + 0u, this_ic); #ifdef CCL_DEBUG { int i = ccl_backtrace_idx - 1; diff --git a/src/character.c b/src/character.c index c143c0f..f51d971 100644 --- a/src/character.c +++ b/src/character.c @@ -841,7 +841,7 @@ string_escape_byte8 (Lisp_Object string) { c = STRING_CHAR_ADVANCE (src); c = CHAR_TO_BYTE8 (c); - dst += sprintf ((char *) dst, "\\%03o", c); + dst += sprintf ((char *) dst, "\\%03o", c + 0u); } else while (len--) *dst++ = *src++; @@ -851,7 +851,7 @@ string_escape_byte8 (Lisp_Object string) { c = *src++; if (c >= 0x80) - dst += sprintf ((char *) dst, "\\%03o", c); + dst += sprintf ((char *) dst, "\\%03o", c + 0u); else *dst++ = c; } diff --git a/src/dbusbind.c b/src/dbusbind.c index 54e92cc..fa26f9e 100644 --- a/src/dbusbind.c +++ b/src/dbusbind.c @@ -874,7 +874,7 @@ xd_retrieve_arg (int dtype, DBusMessageIter *iter) uprintmax_t pval; dbus_message_iter_get_basic (iter, &val); pval = val; - XD_DEBUG_MESSAGE ("%c %"pMd, dtype, pval); + XD_DEBUG_MESSAGE ("%c %"pMu, dtype, pval); return make_fixnum_or_float (val); } @@ -990,7 +990,7 @@ xd_add_watch (DBusWatch *watch, void *data) unsigned int flags = dbus_watch_get_flags (watch); int fd = xd_find_watch_fd (watch); - XD_DEBUG_MESSAGE ("fd %d, write %d, enabled %d", + XD_DEBUG_MESSAGE ("fd %d, write %u, enabled %u", fd, flags & DBUS_WATCH_WRITABLE, dbus_watch_get_enabled (watch)); diff --git a/src/gnutls.c b/src/gnutls.c index ddd36a9..9b8ae2b 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1512,7 +1512,7 @@ one trustfile (usually a CA bundle). */) || !NILP (Fmember (QCgnutls_bootprop_trustfiles, verify_error))) { emacs_gnutls_deinit (proc); - error ("Certificate validation failed %s, verification code %d", + error ("Certificate validation failed %s, verification code %u", c_hostname, peer_verification); } else diff --git a/src/gtkutil.c b/src/gtkutil.c index 41cc7a7..b51d338 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -579,9 +579,9 @@ xg_check_special_colors (struct frame *f, gtk_style_context_get_background_color (gsty, state, &col); sprintf (buf, "rgb:%04x/%04x/%04x", - (int)(col.red * 65535), - (int)(col.green * 65535), - (int)(col.blue * 65535)); + (unsigned) (col.red * 65535), + (unsigned) (col.green * 65535), + (unsigned) (col.blue * 65535)); success_p = (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f), buf, color) != 0); diff --git a/src/image.c b/src/image.c index df299bb..5e48438 100644 --- a/src/image.c +++ b/src/image.c @@ -4964,7 +4964,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) if (i == 3 && NILP (how)) { char color_name[30]; - sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); + sprintf (color_name, "#%04x%04x%04x", + rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u); bg = ( #ifdef HAVE_NTGUI 0x00ffffff & /* Filter out palette info. */ @@ -5729,6 +5730,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) /* Find out what file to load. */ specified_file = image_spec_value (img->spec, QCfile, NULL); specified_data = image_spec_value (img->spec, QCdata, NULL); + IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data); if (NILP (specified_data)) { @@ -5825,6 +5827,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) /* Silence a bogus diagnostic; see GCC bug 54561. */ IF_LINT (fp = c->fp); + IF_LINT (specified_data = specified_data_volatile); /* Read image info. */ if (!NILP (specified_data)) @@ -6467,6 +6470,7 @@ jpeg_load_body (struct frame *f, struct image *img, /* Open the JPEG file. */ specified_file = image_spec_value (img->spec, QCfile, NULL); specified_data = image_spec_value (img->spec, QCdata, NULL); + IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data); if (NILP (specified_data)) { @@ -6528,6 +6532,9 @@ jpeg_load_body (struct frame *f, struct image *img, return 0; } + /* Silence a bogus diagnostic; see GCC bug 54561. */ + IF_LINT (specified_data = specified_data_volatile); + /* Create the JPEG decompression object. Let it read from fp. Read the JPEG image header. */ jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); diff --git a/src/print.c b/src/print.c index bff5932..206466c 100644 --- a/src/print.c +++ b/src/print.c @@ -794,9 +794,12 @@ safe_debug_print (Lisp_Object arg) if (valid > 0) debug_print (arg); else - fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n", - !valid ? "INVALID" : "SOME", - XLI (arg)); + { + EMACS_UINT n = XLI (arg); + fprintf (stderr, "#<%s_LISP_OBJECT 0x%08"pI"x>\r\n", + !valid ? "INVALID" : "SOME", + n); + } } @@ -1422,7 +1425,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) print single-byte non-ASCII string chars using octal escapes. */ char outbuf[5]; - int len = sprintf (outbuf, "\\%03o", c); + int len = sprintf (outbuf, "\\%03o", c + 0u); strout (outbuf, len, len, printcharfun); need_nonhex = false; } @@ -1431,7 +1434,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) { /* When requested, print multibyte chars using hex escapes. */ char outbuf[sizeof "\\x" + INT_STRLEN_BOUND (c)]; - int len = sprintf (outbuf, "\\x%04x", c); + int len = sprintf (outbuf, "\\x%04x", c + 0u); strout (outbuf, len, len, printcharfun); need_nonhex = true; } @@ -2094,11 +2097,11 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) Probably should just emacs_abort (). */ print_c_string ("#"), diff --git a/src/term.c b/src/term.c index 15d33b4..d2a9c3d 100644 --- a/src/term.c +++ b/src/term.c @@ -1862,9 +1862,11 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym) else { eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE); - len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c) - : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c) - : sprintf (buf, "\\x%06X", it->c)); + len = sprintf (buf, + (it->c < 0x10000 ? "\\u%04X" + : it->c <= MAX_UNICODE_CHAR ? "\\U%06X" + : "\\x%06X"), + it->c + 0u); } str = buf; } diff --git a/src/xdisp.c b/src/xdisp.c index 6ca1906..5a27adc 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6971,7 +6971,7 @@ get_next_display_element (struct it *it) if (CHAR_BYTE8_P (c)) /* Display \200 instead of \17777600. */ c = CHAR_TO_BYTE8 (c); - len = sprintf (str, "%03o", c); + len = sprintf (str, "%03o", c + 0u); XSETINT (it->ctl_chars[0], escape_glyph); for (i = 0; i < len; i++) @@ -26233,7 +26233,7 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym) else { eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE); - sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c); + sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u); str = buf; } for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++) diff --git a/src/xterm.c b/src/xterm.c index 48b250b..d9032fa 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1285,7 +1285,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) { sprintf (buf, "%0*X", glyph->u.glyphless.ch < 0x10000 ? 4 : 6, - glyph->u.glyphless.ch); + glyph->u.glyphless.ch + 0u); str = buf; } commit 5933886920fefe800747baf7863685b9dc961d83 Author: Tassilo Horn Date: Fri Apr 24 23:33:19 2015 +0200 Add new faces to tsdh-light-theme * etc/themes/tsdh-light-theme.el (tsdh-light): New face definitions for Info-quoted, ace-jump-face-foreground, hl-paren-face, show-paren-match, and show-paren-mismatch. diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index f85f2ba..6555e49 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -25,6 +25,8 @@ Used and created by Tassilo Horn.") (custom-theme-set-faces 'tsdh-light + '(Info-quoted ((t (:weight bold)))) + '(ace-jump-face-foreground ((t (:foreground "DeepPink" :box (:line-width -1 :color "grey75") :weight bold)))) '(default ((t (:background "white" :foreground "black")))) '(diff-added ((t (:inherit diff-changed :background "light green")))) '(diff-changed ((t (:background "light steel blue")))) @@ -48,6 +50,7 @@ Used and created by Tassilo Horn.") '(gnus-group-news-3 ((t (:inherit gnus-group-news-3-empty :weight bold)))) '(gnus-group-news-3-empty ((t (:foreground "tomato2")))) '(header-line ((t (:inherit mode-line :inverse-video t)))) '(hl-line ((t (:background "grey95")))) + '(hl-paren-face ((t (:weight bold))) t) '(minibuffer-prompt ((t (:background "yellow" :foreground "medium blue" :box (:line-width -1 :color "red" :style released-button) :weight bold)))) '(mode-line ((t (:background "wheat" :foreground "black" :box (:line-width 1 :color "tan") :family "DejaVu Sans")))) '(mode-line-inactive ((t (:inherit mode-line :foreground "dark gray")))) @@ -75,8 +78,8 @@ Used and created by Tassilo Horn.") '(outline-8 ((t (:inherit font-lock-string-face :weight bold)))) '(rcirc-my-nick ((t (:foreground "LightSkyBlue" :weight bold)))) '(region ((t (:background "lightgoldenrod1")))) - '(show-paren-match ((t (:background "LightCyan2")))) - '(show-paren-mismatch ((t (:background "deep pink")))) + '(show-paren-match ((t (:background "Cyan1" :weight bold)))) + '(show-paren-mismatch ((t (:background "deep pink" :weight bold)))) '(window-number-face ((t (:foreground "red" :weight bold))))) (provide-theme 'tsdh-light) commit 7ecda8a22194462114f42225e6d64aaae23c5f6d Author: Nicolas Petton Date: Fri Apr 24 23:12:50 2015 +0200 * lisp/emacs-lisp/seq.el (seq-doseq): Fix the macro. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index b8647ec..0050ff0 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -50,12 +50,12 @@ Evaluate BODY with VAR bound to each element of SEQ, in turn. \(fn (VAR SEQ) BODY...)" (declare (indent 1) (debug ((symbolp form &optional form) body))) - (let ((is-list (make-symbol "is-list")) + (let ((length (make-symbol "length")) (seq (make-symbol "seq")) (index (make-symbol "index"))) `(let* ((,seq ,(cadr spec)) (,length (if (listp ,seq) nil (seq-length ,seq))) - (,index (if ,is-list ,seq 0))) + (,index (if ,length 0 ,seq))) (while (if ,length (< ,index ,length) (consp ,index)) commit ac491b6cf9667e4e68e118eb6db03841599b730f Author: Glenn Morris Date: Fri Apr 24 16:16:01 2015 -0400 * build-aux/gitlog-to-emacslog: Use raw log format rather than wrapped one. diff --git a/build-aux/gitlog-to-emacslog b/build-aux/gitlog-to-emacslog index d994d14..996f6d0 100755 --- a/build-aux/gitlog-to-emacslog +++ b/build-aux/gitlog-to-emacslog @@ -34,6 +34,7 @@ test -d ${srcprefix}.git || { # Use Gnulib's packaged ChangeLog generator. ${srcprefix}build-aux/gitlog-to-changelog --ignore-matching='^; ' \ + --format='%B' \ "$gen_origin.." >"${distprefix}ChangeLog.tmp" || exit if test -s "${distprefix}ChangeLog.tmp"; then commit e224c9465dfe7033b11c0aeb830298c101c9bdcc Author: Stefan Monnier Date: Fri Apr 24 16:11:35 2015 -0400 * lisp/emacs-lisp/seq.el (seq-doseq): Tighten the code (seq-doseq): Fix out-of-scope binding. Don't call `seq-length at every iteration. Reduce `if's from 3 to 2 per iteration. (emacs-lisp-mode-hook): Don't tweak in Emacs≥25. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index e1330f7..b48fae4 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -790,7 +790,7 @@ of type @var{type}. @var{type} can be one of the following symbols: @end example @end defun -@defmac seq-doseq (var sequence [result]) body@dots{} +@defmac seq-doseq (var sequence) body@dots{} @cindex sequence iteration This macro is like @code{dolist}, except that @var{sequence} can be a list, vector or string (@pxref{Iteration} for more information about the diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 320ee20..b8647ec 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -44,31 +44,28 @@ (defmacro seq-doseq (spec &rest body) "Loop over a sequence. -Similar to `dolist' but can be applied lists, strings and vectors. +Similar to `dolist' but can be applied to lists, strings, and vectors. Evaluate BODY with VAR bound to each element of SEQ, in turn. -Then evaluate RESULT to get return value, default nil. -\(fn (VAR SEQ [RESULT]) BODY...)" +\(fn (VAR SEQ) BODY...)" (declare (indent 1) (debug ((symbolp form &optional form) body))) (let ((is-list (make-symbol "is-list")) (seq (make-symbol "seq")) (index (make-symbol "index"))) `(let* ((,seq ,(cadr spec)) - (,is-list (listp ,seq)) + (,length (if (listp ,seq) nil (seq-length ,seq))) (,index (if ,is-list ,seq 0))) - (while (if ,is-list - (consp ,index) - (< ,index (seq-length ,seq))) - (let ((,(car spec) (if ,is-list - (car ,index) - (seq-elt ,seq ,index)))) - ,@body - (setq ,index (if ,is-list - (cdr ,index) - (+ ,index 1))))) - ,@(if (cddr spec) - `((setq ,(car spec) nil) ,@(cddr spec)))))) + (while (if ,length + (< ,index ,length) + (consp ,index)) + (let ((,(car spec) (if ,length + (prog1 (seq-elt ,seq ,index) + (setq ,index (+ ,index 1))) + (pop ,index)))) + ,@body)) + ;; FIXME: Do we really want to support this? + ,@(cddr spec)))) (defun seq-drop (seq n) "Return a subsequence of SEQ without its first N elements. @@ -350,7 +347,10 @@ This is an optimization for lists in `seq-take-while'." (defalias 'seq-each #'seq-do) (defalias 'seq-map #'mapcar) -(add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords) +(unless (fboundp 'elisp--font-lock-flush-elisp-buffers) + ;; In Emacs≥25, (via elisp--font-lock-flush-elisp-buffers and a few others) + ;; we automatically highlight macros. + (add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)) (provide 'seq) ;;; seq.el ends here commit 18a78f8215cc0052bf41d23b8d594cde50d776dd Author: Glenn Morris Date: Fri Apr 24 14:49:12 2015 -0400 * lisp/textmodes/text-mode.el (text-mode-hook): Move text-mode-hook-identify to default. diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el index 84b578b..7effa6a 100644 --- a/lisp/textmodes/text-mode.el +++ b/lisp/textmodes/text-mode.el @@ -29,7 +29,9 @@ ;;; Code: -(defcustom text-mode-hook nil +;; Normally non-nil defaults for hooks are bad, but since this file is +;; preloaded it's ok/better, and avoids this showing up in customize-rogue. +(defcustom text-mode-hook '(text-mode-hook-identify) "Normal hook run when entering Text mode and many related modes." :type 'hook :options '(turn-on-auto-fill turn-on-flyspell) @@ -153,8 +155,6 @@ Turning on Paragraph-Indent minor mode runs the normal hook This is how `toggle-text-mode-auto-fill' knows which buffers to operate on." (set (make-local-variable 'text-mode-variant) t)) -(add-hook 'text-mode-hook 'text-mode-hook-identify) - (defun toggle-text-mode-auto-fill () "Toggle whether to use Auto Fill in Text mode and related modes. This command affects all buffers that use modes related to Text mode, commit b94d950a0a07294d08cdf1514115d2e0dbb44bbf Author: Glenn Morris Date: Fri Apr 24 14:47:30 2015 -0400 ; * lisp/server.el: Comment. diff --git a/lisp/server.el b/lisp/server.el index 9585b17..29d2160 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -245,6 +245,7 @@ in this way." :type 'boolean :version "21.1") +;; FIXME? This is not a minor mode; what's the point of this? (See bug#20201) (or (assq 'server-buffer-clients minor-mode-alist) (push '(server-buffer-clients " Server") minor-mode-alist)) commit 5bc9f498de5cc11091588d14e1e27bebb1a08849 Author: Glenn Morris Date: Fri Apr 24 14:46:42 2015 -0400 * lisp/mouse.el (minor-mode-menu-from-indicator): Handle non-function members of minor-mode-map-alist. (Bug#20201) diff --git a/lisp/mouse.el b/lisp/mouse.el index 5f3fa5d..7854d32 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -152,13 +152,16 @@ items `Turn Off' and `Help'." (setq menu (if menu (mouse-menu-non-singleton menu) - `(keymap - ,indicator - (turn-off menu-item "Turn Off minor mode" ,mm-fun) - (help menu-item "Help for minor mode" - (lambda () (interactive) - (describe-function ',mm-fun)))))) - (popup-menu menu)))) + (if (fboundp mm-fun) ; bug#20201 + `(keymap + ,indicator + (turn-off menu-item "Turn Off minor mode" ,mm-fun) + (help menu-item "Help for minor mode" + (lambda () (interactive) + (describe-function ',mm-fun))))))) + (if menu + (popup-menu menu) + (message "No menu available"))))) (defun mouse-minor-mode-menu (event) "Show minor-mode menu for EVENT on minor modes area of the mode line." commit 82d0f42a4c52196d275470f69788dabf1141765b Author: Glenn Morris Date: Fri Apr 24 14:44:33 2015 -0400 * lisp/help-fns.el (describe-function): More type checking. (describe-function-1): Handle changed symbol-function. (Bug#20201) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 53f4b38..9020037 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -54,20 +54,22 @@ The functions will receive the function name as argument.") (and fn (symbol-name fn)))) (list (if (equal val "") fn (intern val))))) - (if (null function) - (message "You didn't specify a function") - (help-setup-xref (list #'describe-function function) - (called-interactively-p 'interactive)) - (save-excursion - (with-help-window (help-buffer) - (prin1 function) - ;; Use " is " instead of a colon so that - ;; it is easier to get out the function name using forward-sexp. - (princ " is ") - (describe-function-1 function) - (with-current-buffer standard-output - ;; Return the text we displayed. - (buffer-string)))))) + (or (and function (symbolp function)) + (user-error "You didn't specify a function symbol")) + (or (fboundp function) + (user-error "Symbol's function definition is void: %s" function)) + (help-setup-xref (list #'describe-function function) + (called-interactively-p 'interactive)) + (save-excursion + (with-help-window (help-buffer) + (prin1 function) + ;; Use " is " instead of a colon so that + ;; it is easier to get out the function name using forward-sexp. + (princ " is ") + (describe-function-1 function) + (with-current-buffer standard-output + ;; Return the text we displayed. + (buffer-string))))) ;; Could be this, if we make symbol-file do the work below. @@ -479,7 +481,8 @@ FILE is the file where FUNCTION was probably defined." function)) ;; Get the real definition. (def (if (symbolp real-function) - (symbol-function real-function) + (or (symbol-function real-function) + (signal 'void-function (list real-function))) real-function)) (aliased (or (symbolp def) ;; Advised & aliased function. commit 9eabc76e5b6079c4a97964db83e2b6f53fd0f436 Author: Glenn Morris Date: Fri Apr 24 14:34:37 2015 -0400 * build-aux/gitlog-to-emacslog: Convert "Fixes:" to "(Bug#)". Fixes: debbugs:20325 diff --git a/build-aux/gitlog-to-emacslog b/build-aux/gitlog-to-emacslog index 2b82115..d994d14 100755 --- a/build-aux/gitlog-to-emacslog +++ b/build-aux/gitlog-to-emacslog @@ -4,6 +4,8 @@ # Copyright (C) 2014-2015 Free Software Foundation, Inc. +# Author: Paul Eggert + # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -17,8 +19,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Written by Paul Eggert - LC_ALL=C export LC_ALL @@ -38,6 +38,14 @@ ${srcprefix}build-aux/gitlog-to-changelog --ignore-matching='^; ' \ if test -s "${distprefix}ChangeLog.tmp"; then + # Fix up bug references. + # This would be better as eg a --transform option to gitlog-to-changelog, + # but... effort. FIXME does not handle rare cases like: + # Fixes: debbugs:19434 debbugs:19519 + sed 's/ Fixes: \(debbugs:\|bug#\)\([0-9][0-9]*\)/ (Bug#\2)/' \ + "${distprefix}ChangeLog.tmp" > "${distprefix}ChangeLog.tmp2" + mv "${distprefix}ChangeLog.tmp2" "${distprefix}ChangeLog.tmp" + # Find the years covered by the generated ChangeLog, so that # a proper copyright notice can be output. years=` commit 2f3011a46671c255838dc35e77e1ae66dc50b857 Author: Andreas Schwab Date: Fri Apr 24 17:18:55 2015 +0200 shr: strip leading whitespace when expanding URLs * lisp/net/shr.el (shr-expand-url): Strip leading whitespace from URL. diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 9d88d1f..454332e 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -709,6 +709,9 @@ size, and full-buffer size." shr-base)) (when (zerop (length url)) (setq url nil)) + ;; Strip leading whitespace + (and url (string-match "\\`\\s-+" url) + (setq url (substring url (match-end 0)))) (cond ((or (not url) (not base) (string-match "\\`[a-z]*:" url)) commit 422f15d9d66c9f1907b3efb824f1e7f614ba9963 Author: Eli Zaretskii Date: Fri Apr 24 18:00:02 2015 +0300 Clarify "co-authored" some more diff --git a/CONTRIBUTE b/CONTRIBUTE index 9aa76d5..bf23155 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -77,7 +77,7 @@ messages: individual files section. - If the commit has more than one author, the commit message should - contain a separate line to mention the other authors, like the + contain separate lines to mention the other authors, like the following: Co-authored-by: Joe Schmoe commit b20165407673cf4a4240505a9132410ee24ce4eb Author: Eli Zaretskii Date: Fri Apr 24 17:47:23 2015 +0300 * CONTRIBUTE: Clarify "co-authored-by". (Bug#20400) diff --git a/CONTRIBUTE b/CONTRIBUTE index 1e04e3b..9aa76d5 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -76,8 +76,9 @@ messages: file first line (starting with the asterisk). Then there is no individual files section. -- If the commit has authors other than yourself, the commit message - should contain a separate line like the following: +- If the commit has more than one author, the commit message should + contain a separate line to mention the other authors, like the + following: Co-authored-by: Joe Schmoe