libbb: more compact API for bb_parse_mode()
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 7 Oct 2015 15:55:33 +0000 (17:55 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 7 Oct 2015 15:55:33 +0000 (17:55 +0200)
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>
coreutils/chmod.c
coreutils/install.c
coreutils/libcoreutils/getopt_mk_fifo_nod.c
coreutils/mkdir.c
findutils/find.c
include/libbb.h
libbb/parse_mode.c
shell/ash.c
shell/hush.c
util-linux/mdev.c

index 5ee45b94206fa9ad5a6451090234900d078ba44f..a21c6d501871e9d1ddfb44a7580f38fc3f6d6d45 100644 (file)
@@ -69,9 +69,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void
                if (S_ISLNK(statbuf->st_mode))
                        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);
 
        if (chmod(fileName, newmode) == 0) {
index 73f9c70d573e30dec4690245e28d406a12b42e19..8aa51cc3423cdf4ac44b1c7c94591e5d0f4b7e6d 100644 (file)
@@ -159,7 +159,7 @@ int install_main(int argc, char **argv)
        }
        mode = 0755; /* GNU coreutils 6.10 compat */
        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();
        gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();
 
index 222717149443fdd45eb28a957edb4ebb3dd8bb17..47375ff9154b6bf76e4615fa52fd1102c3574d96 100644 (file)
@@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv)
        int opt;
        opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext));
        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);
        }
 
index 864edfb0a1873f733d0605985aaaa0c59bf72387..6f7b004dd3ca3db9f48d2de13a5bec02e1f7e7d8 100644 (file)
@@ -71,8 +71,8 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv)
 #endif
        opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext));
        if (opt & 1) {
-               mode_t mmode = 0777;
-               if (!bb_parse_mode(smode, &mmode)) {
+               mode_t mmode = bb_parse_mode(smode, 0777);
+               if (mmode == (mode_t)-1) {
                        bb_error_msg_and_die("invalid mode '%s'", smode);
                }
                mode = mmode;
index ced8922e7051a5c482550fd3fbf2d0fffd787b55..f72cad7d171acfb7915800b9c859a6df2fc610b4 100644 (file)
@@ -1261,7 +1261,8 @@ static action*** parse_params(char **argv)
                        ap->perm_char = arg1[0];
                        arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1));
                        /*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);
                }
 #endif
index 543214ea4aaa086d89d9c58ec1bd7a48bd14c0ee..d79843a2d72d9c27cb7d386ac608e297dc28c10a 100644 (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;
 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
index 5a4e1c579c3fdfa1c330b61f16fded15e98f05a5..bddd39bca9d9b113238b6d46a352db5780b4dc5b 100644 (file)
@@ -15,7 +15,7 @@
 
 #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[] = {
                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);
                if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
-                       return 0;
+                       return -1;
                }
-               *current_mode = tmp;
-               return 1;
+               return tmp;
        }
 
-       new_mode = *current_mode;
+       new_mode = current_mode;
 
        /* Note: we allow empty clauses, and hence empty modes.
         * 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) {
                                wholist |= who_mask[(int)(p-who_chars)];
                                if (!*++s) {
-                                       return 0;
+                                       return -1;
                                }
                                goto WHO_LIST;
                        }
@@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
                do {    /* Process action list. */
                        if ((*s != '+') && (*s != '-')) {
                                if (*s != '=') {
-                                       return 0;
+                                       return -1;
                                }
                                /* Since op is '=', clear all bits corresponding to the
                                 * 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 != ','));
        }
 
-       *current_mode = new_mode;
-       return 1;
+       return new_mode;
 }
index 80dfc1d6aa76579bdcc9e5c674bac7c41656219d..ab8ec006f5fa5cbfb5ca6f3d4e8e463bfca61235 100644 (file)
@@ -12862,7 +12862,8 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
                 /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */
                if (!isdigit(modestr[0]))
                        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);
                }
                if (!isdigit(modestr[0]))
index 8b8d5fc8b5a3e0816946a175a846273ba3958866..bccd9c1e9c1fce0cd864c4eeaa304751d87f787c 100644 (file)
@@ -8965,6 +8965,7 @@ static int FAST_FUNC builtin_umask(char **argv)
        int rc;
        mode_t mask;
 
+       rc = 1;
        mask = umask(0);
        argv = skip_dash_dash(argv);
        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) */
                if (!isdigit(argv[0][0]))
                        mask ^= 0777;
-               rc = bb_parse_mode(argv[0], &mask);
+               mask = bb_parse_mode(argv[0], mask);
                if (!isdigit(argv[0][0]))
                        mask ^= 0777;
-               if (rc == 0 || (unsigned)mask > 0777) {
+               if ((unsigned)mask > 0777) {
                        mask = old_mask;
                        /* bash messages:
                         * bash: umask: 'q': invalid symbolic mode operator
                         * bash: umask: 999: octal number out of range
                         */
                        bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]);
+                       rc = 0;
                }
        } else {
-               rc = 1;
                /* Mimic bash */
                printf("%04o\n", (unsigned) mask);
                /* fall through and restore mask which we set to 0 */
index 662e8ab38b0762256439f531296c94195b27de03..51781d5978c73dadeeaba1e103df3020e6729707 100644 (file)
@@ -406,7 +406,7 @@ static void parse_next_rule(void)
                }
 
                /* 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 */
                val = tokens[3];