summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sysif.c6
-rw-r--r--tests/018/chmod.tl11
2 files changed, 8 insertions, 9 deletions
diff --git a/sysif.c b/sysif.c
index ee219ff3..44e236d7 100644
--- a/sysif.c
+++ b/sysif.c
@@ -643,14 +643,14 @@ static val chmod_wrap(val target, val mode)
bits |= S_ISVTX;
if (implicit_all || (who & CHM_U) != 0) {
- mask |= 0700;
+ mask |= (0700 | S_ISUID);
if ((srcm & 010))
bits |= S_ISUID;
bits |= (srcm & 7) << 6;
}
if (implicit_all || (who & CHM_G) != 0) {
- mask |= 0070;
+ mask |= (0070 | S_ISGID);
if ((srcm & 010))
bits |= S_ISGID;
bits |= (srcm & 7) << 3;
@@ -675,8 +675,6 @@ static val chmod_wrap(val target, val mode)
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 16b96ad0..f815548c 100644
--- a/tests/018/chmod.tl
+++ b/tests/018/chmod.tl
@@ -19,8 +19,8 @@
(let* ((st (stat tgt))
(m (logand st.mode #xFFF)))
(unless (eql m exp)
- (error "failed to set mode: expected ~s, actual ~s"
- expected (enc-perm m))))))
+ (error "failed to set mode with ~s: expected ~s, actual ~s"
+ mode expected (enc-perm m))))))
(remove-path tgt)
(with-stream (s (open-file tgt "w")))
@@ -32,10 +32,11 @@
(cht "------------" "g+s" "-g----------")
(cht "------------" "+t" "--t---------")
(cht "sgtrwxrwxrwx" "=" "------------")
-(cht "sgtrwxrwxrwx" "u=" "--t---rwxrwx")
-(cht "sgtrwxrwxrwx" "g=" "--trwx---rwx")
-(cht "sgtrwxrwxrwx" "o=" "---rwxrwx---")
+(cht "sgtrwxrwxrwx" "u=" "-gt---rwxrwx")
+(cht "sgtrwxrwxrwx" "g=" "s-trwx---rwx")
+(cht "sgtrwxrwxrwx" "o=" "sg-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")
+(cht "---------rwx" "u=rwsx,g=rwx,go-x" "s--rwxrw-rw-")