hush: fix umask: umask(022) was setting umask(755)

Based on the patch by Rich Felker <dalias@libc.org>

function                                             old     new   delta
builtin_umask                                        121     161     +40
umaskcmd                                             318     279     -39

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2015-10-07 16:56:20 +02:00
parent 9c5410023a
commit 6283f98283
2 changed files with 20 additions and 24 deletions

View File

@ -12814,7 +12814,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
} }
static int FAST_FUNC static int FAST_FUNC
umaskcmd(int argc UNUSED_PARAM, char **argv) umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
{ {
static const char permuser[3] ALIGN1 = "ugo"; static const char permuser[3] ALIGN1 = "ugo";
static const char permmode[3] ALIGN1 = "rwx"; static const char permmode[3] ALIGN1 = "rwx";
@ -12824,9 +12824,6 @@ umaskcmd(int argc UNUSED_PARAM, char **argv)
S_IROTH, S_IWOTH, S_IXOTH S_IROTH, S_IWOTH, S_IXOTH
}; };
/* TODO: use bb_parse_mode() instead */
char *ap;
mode_t mask; mode_t mask;
int i; int i;
int symbolic_mode = 0; int symbolic_mode = 0;
@ -12840,8 +12837,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv)
umask(mask); umask(mask);
INT_ON; INT_ON;
ap = *argptr; if (*argptr == NULL) {
if (ap == NULL) {
if (symbolic_mode) { if (symbolic_mode) {
char buf[18]; char buf[18];
char *p = buf; char *p = buf;
@ -12858,27 +12854,23 @@ umaskcmd(int argc UNUSED_PARAM, char **argv)
} }
*p++ = ','; *p++ = ',';
} }
*--p = 0; *--p = '\0';
puts(buf); puts(buf);
} else { } else {
out1fmt("%.4o\n", mask); out1fmt("%.4o\n", mask);
} }
} else { } else {
if (isdigit((unsigned char) *ap)) { char *modestr = *argptr;
mask = 0; /* numeric umasks are taken as-is */
do { /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
if (*ap >= '8' || *ap < '0') if (!isdigit(modestr[0]))
ash_msg_and_raise_error(msg_illnum, argv[1]); mask ^= 0777;
mask = (mask << 3) + (*ap - '0'); if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) {
} while (*++ap != '\0'); ash_msg_and_raise_error("illegal mode: %s", modestr);
umask(mask);
} else {
mask = ~mask & 0777;
if (!bb_parse_mode(ap, &mask)) {
ash_msg_and_raise_error("illegal mode: %s", ap);
}
umask(~mask & 0777);
} }
if (!isdigit(modestr[0]))
mask ^= 0777;
umask(mask);
} }
return 0; return 0;
} }

View File

@ -8970,10 +8970,14 @@ static int FAST_FUNC builtin_umask(char **argv)
if (argv[0]) { if (argv[0]) {
mode_t old_mask = mask; mode_t old_mask = mask;
mask ^= 0777; /* numeric umasks are taken as-is */
/* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
if (!isdigit(argv[0][0]))
mask ^= 0777;
rc = bb_parse_mode(argv[0], &mask); rc = bb_parse_mode(argv[0], &mask);
mask ^= 0777; if (!isdigit(argv[0][0]))
if (rc == 0) { mask ^= 0777;
if (rc == 0 || (unsigned)mask > 0777) {
mask = old_mask; mask = old_mask;
/* bash messages: /* bash messages:
* bash: umask: 'q': invalid symbolic mode operator * bash: umask: 'q': invalid symbolic mode operator