[git commit] libbb: more compact API for bb_parse_mode()

Denys Vlasenko vda.linux at googlemail.com
Wed Oct 7 15:55:33 UTC 2015


commit: http://git.busybox.net/busybox/commit/?id=5711a2a4ad51ad203a2ed4ffc72593e83920b36a
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 coreutils/chmod.c                           |    4 ++--
 coreutils/install.c                         |    2 +-
 coreutils/libcoreutils/getopt_mk_fifo_nod.c |    4 +++-
 coreutils/mkdir.c                           |    4 ++--
 findutils/find.c                            |    3 ++-
 include/libbb.h                             |    3 ++-
 libbb/parse_mode.c                          |   16 +++++++---------
 shell/ash.c                                 |    3 ++-
 shell/hush.c                                |    7 ++++---
 util-linux/mdev.c                           |    2 +-
 10 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index 5ee45b9..a21c6d5 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -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) {
diff --git a/coreutils/install.c b/coreutils/install.c
index 73f9c70..8aa51cc 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -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();
 
diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c
index 2227171..47375ff 100644
--- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c
+++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c
@@ -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);
 	}
 
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c
index 864edfb..6f7b004 100644
--- a/coreutils/mkdir.c
+++ b/coreutils/mkdir.c
@@ -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;
diff --git a/findutils/find.c b/findutils/find.c
index ced8922..f72cad7 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -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
diff --git a/include/libbb.h b/include/libbb.h
index 543214e..d79843a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -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
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c
index 5a4e1c5..bddd39b 100644
--- a/libbb/parse_mode.c
+++ b/libbb/parse_mode.c
@@ -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;
 }
diff --git a/shell/ash.c b/shell/ash.c
index 80dfc1d..ab8ec00 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -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]))
diff --git a/shell/hush.c b/shell/hush.c
index 8b8d5fc..bccd9c1 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -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 */
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 662e8ab..51781d5 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -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];


More information about the busybox-cvs mailing list