[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] modechange: add notations +40, 00440, etc.
From: |
Paul Eggert |
Subject: |
[PATCH] modechange: add notations +40, 00440, etc. |
Date: |
Thu, 08 Mar 2012 18:09:50 -0800 |
User-agent: |
Mozilla/5.0 (X11; Linux i686; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 |
* lib/modechange.c (mode_compile): Support new notations
+40, -40, =440, 00440. See <http://debbugs.gnu.org/8391>.
---
ChangeLog | 6 +++++
lib/modechange.c | 65 +++++++++++++++++++++++++++++++++++++++---------------
2 files changed, 53 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ac13951..63b35f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-03-08 Paul Eggert <address@hidden>
+
+ 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 <address@hidden>
exp2l-ieee: Work around test failure on OpenBSD 4.9 and IRIX 6.5.
diff --git a/lib/modechange.c b/lib/modechange.c
index 4ae90ca..a84c34a 100644
--- a/lib/modechange.c
+++ b/lib/modechange.c
@@ -136,6 +136,7 @@ mode_compile (char const *mode_string)
/* 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_compile (char const *mode_string)
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 @@ mode_compile (char const *mode_string)
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 @@ mode_compile (char const *mode_string)
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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] modechange: add notations +40, 00440, etc.,
Paul Eggert <=