libbb: more compact API for bb_parse_mode()

function                                             old     new   delta
make_device                                         2182    2188      +6
parse_command                                       1440    1443      +3
parse_params                                        1497    1499      +2
install_main                                         773     769      -4
mkdir_main                                           168     160      -8
getoptscmd                                           641     632      -9
builtin_umask                                        158     147     -11
bb_parse_mode                                        431     410     -21
umaskcmd                                             286     258     -28
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/6 up/down: 11/-81)            Total: -70 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2015-10-07 17:55:33 +02:00
parent c1e2e005b4
commit 5711a2a4ad
10 changed files with 26 additions and 22 deletions

View File

@ -69,9 +69,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void
if (S_ISLNK(statbuf->st_mode)) if (S_ISLNK(statbuf->st_mode))
return TRUE; return TRUE;
} }
newmode = statbuf->st_mode;
if (!bb_parse_mode((char *)param, &newmode)) newmode = bb_parse_mode((char *)param, statbuf->st_mode);
if (newmode == (mode_t)-1)
bb_error_msg_and_die("invalid mode '%s'", (char *)param); bb_error_msg_and_die("invalid mode '%s'", (char *)param);
if (chmod(fileName, newmode) == 0) { if (chmod(fileName, newmode) == 0) {

View File

@ -159,7 +159,7 @@ int install_main(int argc, char **argv)
} }
mode = 0755; /* GNU coreutils 6.10 compat */ mode = 0755; /* GNU coreutils 6.10 compat */
if (opts & OPT_MODE) if (opts & OPT_MODE)
bb_parse_mode(mode_str, &mode); mode = bb_parse_mode(mode_str, mode);
uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid();
gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();

View File

@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv)
int opt; int opt;
opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext));
if (opt & 1) { if (opt & 1) {
if (bb_parse_mode(smode, &mode)) mode = bb_parse_mode(smode, mode);
if (mode != (mode_t)-1) /* if mode is valid */
/* make future mknod/mkfifo set mode bits exactly */
umask(0); umask(0);
} }

View File

@ -71,8 +71,8 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv)
#endif #endif
opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext));
if (opt & 1) { if (opt & 1) {
mode_t mmode = 0777; mode_t mmode = bb_parse_mode(smode, 0777);
if (!bb_parse_mode(smode, &mmode)) { if (mmode == (mode_t)-1) {
bb_error_msg_and_die("invalid mode '%s'", smode); bb_error_msg_and_die("invalid mode '%s'", smode);
} }
mode = mmode; mode = mmode;

View File

@ -1261,7 +1261,8 @@ static action*** parse_params(char **argv)
ap->perm_char = arg1[0]; ap->perm_char = arg1[0];
arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1)); arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1));
/*ap->perm_mask = 0; - ALLOC_ACTION did it */ /*ap->perm_mask = 0; - ALLOC_ACTION did it */
if (!bb_parse_mode(arg1, &ap->perm_mask)) ap->perm_mask = bb_parse_mode(arg1, ap->perm_mask);
if (ap->perm_mask == (mode_t)-1)
bb_error_msg_and_die("invalid mode '%s'", arg1); bb_error_msg_and_die("invalid mode '%s'", arg1);
} }
#endif #endif

View File

@ -1251,7 +1251,8 @@ char *bb_ask_stdin(const char * prompt) FAST_FUNC;
char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC;
int bb_ask_confirmation(void) FAST_FUNC; int bb_ask_confirmation(void) FAST_FUNC;
int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; /* Returns -1 if input is invalid. current_mode is a base for e.g. "u+rw" */
int bb_parse_mode(const char* s, unsigned cur_mode) FAST_FUNC;
/* /*
* Config file parser * Config file parser

View File

@ -15,7 +15,7 @@
#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode)
{ {
static const mode_t who_mask[] = { static const mode_t who_mask[] = {
S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
@ -46,13 +46,12 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
tmp = strtoul(s, &e, 8); tmp = strtoul(s, &e, 8);
if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
return 0; return -1;
} }
*current_mode = tmp; return tmp;
return 1;
} }
new_mode = *current_mode; new_mode = current_mode;
/* Note: we allow empty clauses, and hence empty modes. /* Note: we allow empty clauses, and hence empty modes.
* We treat an empty mode as no change to perms. */ * We treat an empty mode as no change to perms. */
@ -71,7 +70,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
if (*p == *s) { if (*p == *s) {
wholist |= who_mask[(int)(p-who_chars)]; wholist |= who_mask[(int)(p-who_chars)];
if (!*++s) { if (!*++s) {
return 0; return -1;
} }
goto WHO_LIST; goto WHO_LIST;
} }
@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
do { /* Process action list. */ do { /* Process action list. */
if ((*s != '+') && (*s != '-')) { if ((*s != '+') && (*s != '-')) {
if (*s != '=') { if (*s != '=') {
return 0; return -1;
} }
/* Since op is '=', clear all bits corresponding to the /* Since op is '=', clear all bits corresponding to the
* wholist, or all file bits if wholist is empty. */ * wholist, or all file bits if wholist is empty. */
@ -145,6 +144,5 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
} while (*s && (*s != ',')); } while (*s && (*s != ','));
} }
*current_mode = new_mode; return new_mode;
return 1;
} }

View File

@ -12862,7 +12862,8 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
/* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
if (!isdigit(modestr[0])) if (!isdigit(modestr[0]))
mask ^= 0777; mask ^= 0777;
if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { mask = bb_parse_mode(modestr, mask);
if ((unsigned)mask > 0777) {
ash_msg_and_raise_error("illegal mode: %s", modestr); ash_msg_and_raise_error("illegal mode: %s", modestr);
} }
if (!isdigit(modestr[0])) if (!isdigit(modestr[0]))

View File

@ -8965,6 +8965,7 @@ static int FAST_FUNC builtin_umask(char **argv)
int rc; int rc;
mode_t mask; mode_t mask;
rc = 1;
mask = umask(0); mask = umask(0);
argv = skip_dash_dash(argv); argv = skip_dash_dash(argv);
if (argv[0]) { if (argv[0]) {
@ -8974,19 +8975,19 @@ static int FAST_FUNC builtin_umask(char **argv)
/* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
if (!isdigit(argv[0][0])) if (!isdigit(argv[0][0]))
mask ^= 0777; mask ^= 0777;
rc = bb_parse_mode(argv[0], &mask); mask = bb_parse_mode(argv[0], mask);
if (!isdigit(argv[0][0])) if (!isdigit(argv[0][0]))
mask ^= 0777; mask ^= 0777;
if (rc == 0 || (unsigned)mask > 0777) { if ((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
* bash: umask: 999: octal number out of range * bash: umask: 999: octal number out of range
*/ */
bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
rc = 0;
} }
} else { } else {
rc = 1;
/* Mimic bash */ /* Mimic bash */
printf("%04o\n", (unsigned) mask); printf("%04o\n", (unsigned) mask);
/* fall through and restore mask which we set to 0 */ /* fall through and restore mask which we set to 0 */

View File

@ -406,7 +406,7 @@ static void parse_next_rule(void)
} }
/* 3rd field: mode - device permissions */ /* 3rd field: mode - device permissions */
bb_parse_mode(tokens[2], &G.cur_rule.mode); G.cur_rule.mode = bb_parse_mode(tokens[2], G.cur_rule.mode);
/* 4th field (opt): ">|=alias" or "!" to not create the node */ /* 4th field (opt): ">|=alias" or "!" to not create the node */
val = tokens[3]; val = tokens[3];