summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c12
-rw-r--r--tests/018/chmod.tl7
2 files changed, 14 insertions, 5 deletions
diff --git a/sysif.c b/sysif.c
index 286dcca6..ee219ff3 100644
--- a/sysif.c
+++ b/sysif.c
@@ -671,11 +671,13 @@ static val chmod_wrap(val target, val mode)
case chm_add: cmode |= bits; break;
case chm_sub: cmode &= ~bits; break;
case chm_set:
- cmode &= ~mask;
- if (implicit_all || (who & CHM_O) != 0)
- cmode &= ~S_ISVTX; /* GNU Coreutils 8.28 chmod behavior */
- if (!S_ISDIR(cmode))
- cmode &= ~(S_ISUID | S_ISGID);
+ if (cs == chm_perm) {
+ cmode &= ~mask;
+ if (implicit_all || (who & CHM_O) != 0)
+ cmode &= ~S_ISVTX; /* GNU Coreutils 8.28 chmod behavior */
+ if (!S_ISDIR(cmode))
+ cmode &= ~(S_ISUID | S_ISGID);
+ }
cmode |= bits;
break;
}
diff --git a/tests/018/chmod.tl b/tests/018/chmod.tl
index 7ae0f9b2..16b96ad0 100644
--- a/tests/018/chmod.tl
+++ b/tests/018/chmod.tl
@@ -32,3 +32,10 @@
(cht "------------" "g+s" "-g----------")
(cht "------------" "+t" "--t---------")
(cht "sgtrwxrwxrwx" "=" "------------")
+(cht "sgtrwxrwxrwx" "u=" "--t---rwxrwx")
+(cht "sgtrwxrwxrwx" "g=" "--trwx---rwx")
+(cht "sgtrwxrwxrwx" "o=" "---rwxrwx---")
+(cht "------------" "u+s,g+s" "sg----------")
+(cht "------------" "u+r,g+r,o+r,+t,+s" "sgtr--r--r--")
+(cht "------------" "+rwx,g-r+w,o-r+w" "---rwx-wx-wx")
+(cht "---------rwx" "u=rwsx" "s--rwx---rwx")