chmod: Implement X perm symbol
Instead of clearing the format bits before calling parsemode, leave them in so we can differentiate between directories and other files, then clear the format bits in the result.
This commit is contained in:
parent
e5284b1537
commit
f3d05ffd0a
4
chmod.1
4
chmod.1
@ -47,7 +47,7 @@ If
|
|||||||
.Ar mode
|
.Ar mode
|
||||||
is
|
is
|
||||||
.Em symbolic
|
.Em symbolic
|
||||||
"[ugoa]*[+-=][rwxst]*"
|
"[ugoa]*[+-=][rwxXst]*"
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It u|g|o|a
|
.It u|g|o|a
|
||||||
owner | group | other (non-group) | everyone
|
owner | group | other (non-group) | everyone
|
||||||
@ -55,6 +55,8 @@ owner | group | other (non-group) | everyone
|
|||||||
add | remove | set
|
add | remove | set
|
||||||
.It r|w|x|s|t
|
.It r|w|x|s|t
|
||||||
read | write | execute | setuid and setgid | sticky
|
read | write | execute | setuid and setgid | sticky
|
||||||
|
.It X
|
||||||
|
execute, if directory or at least one execute bit is already set
|
||||||
.El
|
.El
|
||||||
.Sh OPTIONS
|
.Sh OPTIONS
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
6
chmod.c
6
chmod.c
@ -13,7 +13,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r)
|
|||||||
{
|
{
|
||||||
mode_t m;
|
mode_t m;
|
||||||
|
|
||||||
m = parsemode(modestr, st->st_mode & ~S_IFMT, mask);
|
m = parsemode(modestr, st->st_mode, mask);
|
||||||
if (chmod(path, m) < 0) {
|
if (chmod(path, m) < 0) {
|
||||||
weprintf("chmod %s:", path);
|
weprintf("chmod %s:", path);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -50,8 +50,8 @@ main(int argc, char *argv[])
|
|||||||
case 'P':
|
case 'P':
|
||||||
r.follow = (*argv)[i];
|
r.follow = (*argv)[i];
|
||||||
break;
|
break;
|
||||||
case 'r': case 'w': case 'x': case 's': case 't':
|
case 'r': case 'w': case 'x': case 'X': case 's': case 't':
|
||||||
/* -[rwxst] are valid modes, so we're done */
|
/* -[rwxXst] are valid modes, so we're done */
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
goto done;
|
goto done;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
@ -113,6 +113,10 @@ next:
|
|||||||
case 'x':
|
case 'x':
|
||||||
perm |= S_IXUSR|S_IXGRP|S_IXOTH;
|
perm |= S_IXUSR|S_IXGRP|S_IXOTH;
|
||||||
break;
|
break;
|
||||||
|
case 'X':
|
||||||
|
if (S_ISDIR(mode) || mode & (S_IXUSR|S_IXGRP|S_IXOTH))
|
||||||
|
perm |= S_IXUSR|S_IXGRP|S_IXOTH;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
perm |= S_ISUID|S_ISGID;
|
perm |= S_ISUID|S_ISGID;
|
||||||
break;
|
break;
|
||||||
@ -144,5 +148,5 @@ apply:
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mode;
|
return mode & ~S_IFMT;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user