aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-01-06 12:48:28 -0600
committerRob Landley <rob@landley.net>2020-01-06 12:48:28 -0600
commitc25ff2dde84d2af5744a1dc7d0dbd2c14cbaae62 (patch)
treeb181d19f151f3cf968050a2e6a37b784cd5de679
parentc87487ffd9781a1a77a1dcef293e3e706146a4aa (diff)
downloadtoybox-c25ff2dde84d2af5744a1dc7d0dbd2c14cbaae62.tar.gz
SebiderSushi reported that chmod g+s wasn't working.
-rw-r--r--lib/lib.c17
-rwxr-xr-xtests/chmod.test4
2 files changed, 12 insertions, 9 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 26ba546f..b14e2e9f 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -922,12 +922,12 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// If who isn't specified, like "a" but honoring umask.
if (!dowho) {
dowho = 8;
- umask(amask=umask(0));
+ umask(amask = umask(0));
}
+
if (!*str || !(s = strchr(hows, *str))) goto barf;
- dohow = *(str++);
+ if (!(dohow = *(str++))) goto barf;
- if (!dohow) goto barf;
while (*str && (s = strchr(whats, *str))) {
dowhat |= 1<<(s-whats);
str++;
@@ -945,7 +945,7 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// Are we ready to do a thing yet?
if (*str && *(str++) != ',') goto barf;
- // Ok, apply the bits to the mode.
+ // Loop through what=xwrs and who=ogu to apply bits to the mode.
for (i=0; i<4; i++) {
for (j=0; j<3; j++) {
mode_t bit = 0;
@@ -955,13 +955,12 @@ mode_t string_to_mode(char *modestr, mode_t mode)
// Figure out new value at this location
if (i == 3) {
- // suid/sticky bit.
- if (j) {
- if ((dowhat & 8) && (dowho&(8|(1<<i)))) bit++;
- } else if (dowhat & 16) bit++;
+ // suid and sticky
+ if (!j) bit = dowhat&16; // o+s = t
+ else if ((dowhat&8) && (dowho&(8|(1<<j)))) bit++;
} else {
if (!(dowho&(8|(1<<i)))) continue;
- if (dowhat&(1<<j)) bit++;
+ else if (dowhat&(1<<j)) bit++;
}
// When selection active, modify bit
diff --git a/tests/chmod.test b/tests/chmod.test
index cf035f2d..b2b5a488 100755
--- a/tests/chmod.test
+++ b/tests/chmod.test
@@ -107,6 +107,10 @@ chtest +x "drwxr-xr-x\n-rwxr-xr-x\n"
chtest -r "d-wx--x--x\n--w-------\n"
chtest -w "dr-xr-xr-x\n-r--r--r--\n"
chtest -x "drw-r--r--\n-rw-r--r--\n"
+chtest g+s "drwxr-sr-x\n-rw-r-Sr--\n"
+chtest u+s "drwsr-xr-x\n-rwSr--r--\n"
+chtest o+s "drwxr-xr-x\n-rw-r--r--\n"
+chtest +t "drwxr-xr-t\n-rw-r--r-T\n"
# Removing test files for cleanup purpose
rm -rf dir file