changeset 638:92200901cfe1

Make chmod +w respect umask, implement +s and +t, fix ls to show suid/sgid/stid without x bit.
author Rob Landley <rob@landley.net>
date Sat, 21 Jul 2012 22:45:05 -0500
parents 9aeea680acc7
children 3c591e7a367d
files lib/lib.c toys/ls.c
diffstat 2 files changed, 22 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/lib/lib.c	Sat Jul 21 18:38:36 2012 -0500
+++ b/lib/lib.c	Sat Jul 21 22:45:05 2012 -0500
@@ -983,16 +983,20 @@
 
 	// Gaze into the bin of permission...
 	for (;;) {
-		int i, j, dowho, dohow, dowhat;
+		int i, j, dowho, dohow, dowhat, amask;
 
-		dowho = dohow = dowhat = 0;
+		dowho = dohow = dowhat = amask = 0;
 
 		// Find the who, how, and what stanzas, in that order
 		while (*str && (s = strchr(whos, *str))) {
 			dowho |= 1<<(s-whos);
 			str++;
 		}
-		if (!dowho) dowho = 8;
+		// If who isn't specified, like "a" but honoring umask.
+		if (!dowho) {
+			dowho = 8;
+			umask(amask=umask(0));
+		}
 		if (!*str || !(s = strchr(hows, *str))) goto barf;
 		dohow = *(str++);
 
@@ -1018,19 +1022,26 @@
 		for (i=0; i<4; i++) {
 			for (j=0; j<3; j++) {
 				mode_t bit = 0;
+				int where = 1<<((3*i)+j);
+
+				if (amask & where) continue;
 
 				// Figure out new value at this location
 				if (i == 3) {
-				} else if (dowhat&(1<<j)) bit++;
+					// suid/sticky bit.
+					if (j) {
+						if ((dowhat & 8) && (dowho&(8|(1<<i)))) bit++;
+					} else if (dowhat & 16) bit++;
+				} else {
+					if (!(dowho&(8|(1<<i)))) continue;
+					if (dowhat&(1<<j)) bit++;
+				}
 
 				// When selection active, modify bit
-				if (dowho&(8|(1<<i))) {
-					int where = 1<<((3*i)+j);
 
-					if (dohow == '=' || (bit && dohow == '-'))
-						mode &= ~where;
-					if (bit && dohow != '-') mode |= where;
-				}
+				if (dohow == '=' || (bit && dohow == '-'))
+					mode &= ~where;
+				if (bit && dohow != '-') mode |= where;
 			}
 		}
 
--- a/toys/ls.c	Sat Jul 21 18:38:36 2012 -0500
+++ b/toys/ls.c	Sat Jul 21 22:45:05 2012 -0500
@@ -374,7 +374,7 @@
                 c = i%3;
                 if (!c && (mode & (1<<((d=i/3)+9)))) {
                     c = "tss"[d];
-                    if (!bit) c &= 0x20;
+                    if (!bit) c &= ~0x20;
                 } else c = bit ? "xwr"[c] : '-';
                 perm[9-i] = c;
             }