Mercurial > gnulib
changeset 36320:4120a7f10667
modechange: add notations +40, 00440, etc.
* lib/modechange.c (mode_compile): Support new notations
+40, -40, =440, 00440. See <http://debbugs.gnu.org/8391>.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Thu, 08 Mar 2012 18:05:51 -0800 |
parents | e6d36f473079 |
children | 818d43c8c05e |
files | ChangeLog lib/modechange.c |
diffstat | 2 files changed, 53 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Mar 09 02:14:26 2012 +0100 +++ b/ChangeLog Thu Mar 08 18:05:51 2012 -0800 @@ -1,3 +1,9 @@ +2012-03-08 Paul Eggert <eggert@cs.ucla.edu> + + modechange: add notations +40, 00440, etc. + * lib/modechange.c (mode_compile): Support new notations + +40, -40, =440, 00440. See <http://debbugs.gnu.org/8391>. + 2012-03-08 Bruno Haible <bruno@clisp.org> exp2l-ieee: Work around test failure on OpenBSD 4.9 and IRIX 6.5.
--- a/lib/modechange.c Fri Mar 09 02:14:26 2012 +0100 +++ b/lib/modechange.c Thu Mar 08 18:05:51 2012 -0800 @@ -136,6 +136,7 @@ /* The array of mode-change directives to be returned. */ struct mode_change *mc; size_t used = 0; + char const *p; if ('0' <= *mode_string && *mode_string < '8') { @@ -143,40 +144,43 @@ mode_t mode; mode_t mentioned; + p = mode_string; do { - octal_mode = 8 * octal_mode + *mode_string++ - '0'; + octal_mode = 8 * octal_mode + *p++ - '0'; if (ALLM < octal_mode) return NULL; } - while ('0' <= *mode_string && *mode_string < '8'); + while ('0' <= *p && *p < '8'); - if (*mode_string) + if (*p) return NULL; mode = octal_to_mode (octal_mode); - mentioned = (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO; + mentioned = (p - mode_string < 5 + ? (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO + : CHMOD_MODE_BITS); return make_node_op_equals (mode, mentioned); } /* Allocate enough space to hold the result. */ { size_t needed = 1; - char const *p; for (p = mode_string; *p; p++) needed += (*p == '=' || *p == '+' || *p == '-'); mc = xnmalloc (needed, sizeof *mc); } - /* One loop iteration for each '[ugoa]*([-+=]([rwxXst]*|[ugo]))+'. */ - for (;; mode_string++) + /* One loop iteration for each + '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'. */ + for (p = mode_string; ; p++) { /* Which bits in the mode are operated on. */ mode_t affected = 0; /* Turn on all the bits in 'affected' for each group given. */ - for (;; mode_string++) - switch (*mode_string) + for (;; p++) + switch (*p) { default: goto invalid; @@ -199,35 +203,60 @@ do { - char op = *mode_string++; + char op = *p++; mode_t value; + mode_t mentioned = 0; char flag = MODE_COPY_EXISTING; struct mode_change *change; - switch (*mode_string++) + switch (*p) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + unsigned int octal_mode = 0; + + do + { + octal_mode = 8 * octal_mode + *p++ - '0'; + if (ALLM < octal_mode) + return NULL; + } + while ('0' <= *p && *p < '8'); + + if (affected || (*p && *p != ',')) + return NULL; + affected = mentioned = CHMOD_MODE_BITS; + value = octal_to_mode (octal_mode); + flag = MODE_ORDINARY_CHANGE; + break; + } + case 'u': /* Set the affected bits to the value of the "u" bits on the same file. */ value = S_IRWXU; + p++; break; case 'g': /* Set the affected bits to the value of the "g" bits on the same file. */ value = S_IRWXG; + p++; break; case 'o': /* Set the affected bits to the value of the "o" bits on the same file. */ value = S_IRWXO; + p++; break; default: value = 0; flag = MODE_ORDINARY_CHANGE; - for (mode_string--;; mode_string++) - switch (*mode_string) + for (;; p++) + switch (*p) { case 'r': value |= S_IRUSR | S_IRGRP | S_IROTH; @@ -260,16 +289,16 @@ change->flag = flag; change->affected = affected; change->value = value; - change->mentioned = (affected ? affected & value : value); + change->mentioned = + (mentioned ? mentioned : affected ? affected & value : value); } - while (*mode_string == '=' || *mode_string == '+' - || *mode_string == '-'); + while (*p == '=' || *p == '+' || *p == '-'); - if (*mode_string != ',') + if (*p != ',') break; } - if (*mode_string == 0) + if (*p == 0) { mc[used].flag = MODE_DONE; return mc;