sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

commit f3d05ffd0ac4226f9064be5c71606ab9b7d12d92
parent e5284b15378085f541449532798d3d99b13cacd2
Author: Michael Forney <mforney@mforney.org>
Date:   Mon,  6 Jan 2020 13:08:38 -0800

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.

Diffstat:
Mchmod.1 | 4+++-
Mchmod.c | 6+++---
Mlibutil/mode.c | 6+++++-
3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/chmod.1 b/chmod.1 @@ -47,7 +47,7 @@ If .Ar mode is .Em symbolic -"[ugoa]*[+-=][rwxst]*" +"[ugoa]*[+-=][rwxXst]*" .Bl -tag -width Ds .It u|g|o|a owner | group | other (non-group) | everyone @@ -55,6 +55,8 @@ owner | group | other (non-group) | everyone add | remove | set .It r|w|x|s|t read | write | execute | setuid and setgid | sticky +.It X +execute, if directory or at least one execute bit is already set .El .Sh OPTIONS .Bl -tag -width Ds diff --git a/chmod.c b/chmod.c @@ -13,7 +13,7 @@ chmodr(const char *path, struct stat *st, void *data, struct recursor *r) { mode_t m; - m = parsemode(modestr, st->st_mode & ~S_IFMT, mask); + m = parsemode(modestr, st->st_mode, mask); if (chmod(path, m) < 0) { weprintf("chmod %s:", path); ret = 1; @@ -50,8 +50,8 @@ main(int argc, char *argv[]) case 'P': r.follow = (*argv)[i]; break; - case 'r': case 'w': case 'x': case 's': case 't': - /* -[rwxst] are valid modes, so we're done */ + case 'r': case 'w': case 'x': case 'X': case 's': case 't': + /* -[rwxXst] are valid modes, so we're done */ if (i == 1) goto done; /* fallthrough */ diff --git a/libutil/mode.c b/libutil/mode.c @@ -113,6 +113,10 @@ next: case 'x': perm |= S_IXUSR|S_IXGRP|S_IXOTH; break; + case 'X': + if (S_ISDIR(mode) || mode & (S_IXUSR|S_IXGRP|S_IXOTH)) + perm |= S_IXUSR|S_IXGRP|S_IXOTH; + break; case 's': perm |= S_ISUID|S_ISGID; break; @@ -144,5 +148,5 @@ apply: goto next; } } - return mode; + return mode & ~S_IFMT; }