diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/appletlib.c | 9 | ||||
-rw-r--r-- | libbb/bb_strtonum.c | 59 | ||||
-rw-r--r-- | libbb/dump.c | 25 | ||||
-rw-r--r-- | libbb/find_mount_point.c | 3 | ||||
-rw-r--r-- | libbb/isdirectory.c | 15 | ||||
-rw-r--r-- | libbb/lineedit.c | 15 | ||||
-rw-r--r-- | libbb/parse_config.c | 2 | ||||
-rw-r--r-- | libbb/procps.c | 16 | ||||
-rw-r--r-- | libbb/read_printf.c | 139 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 10 | ||||
-rw-r--r-- | libbb/xconnect.c | 16 | ||||
-rw-r--r-- | libbb/xfuncs_printf.c | 1 |
12 files changed, 105 insertions, 205 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 0c675db4d..116e275be 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -632,7 +632,10 @@ static int busybox_main(char **argv) | |||
632 | "See source distribution for full notice.\n" | 632 | "See source distribution for full notice.\n" |
633 | "\n" | 633 | "\n" |
634 | "Usage: busybox [function] [arguments]...\n" | 634 | "Usage: busybox [function] [arguments]...\n" |
635 | " or: busybox --list[-full]\n" | 635 | " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" |
636 | IF_FEATURE_INSTALLER( | ||
637 | " or: busybox --install [-s] [DIR]\n" | ||
638 | ) | ||
636 | " or: function [arguments]...\n" | 639 | " or: function [arguments]...\n" |
637 | "\n" | 640 | "\n" |
638 | "\tBusyBox is a multi-call binary that combines many common Unix\n" | 641 | "\tBusyBox is a multi-call binary that combines many common Unix\n" |
@@ -672,7 +675,7 @@ static int busybox_main(char **argv) | |||
672 | dup2(1, 2); | 675 | dup2(1, 2); |
673 | while (*a) { | 676 | while (*a) { |
674 | # if ENABLE_FEATURE_INSTALLER | 677 | # if ENABLE_FEATURE_INSTALLER |
675 | if (argv[1][6]) /* --list-path? */ | 678 | if (argv[1][6]) /* --list-full? */ |
676 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); | 679 | full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); |
677 | # endif | 680 | # endif |
678 | full_write2_str(a); | 681 | full_write2_str(a); |
@@ -702,7 +705,7 @@ static int busybox_main(char **argv) | |||
702 | * -s: make symlinks | 705 | * -s: make symlinks |
703 | * DIR: directory to install links to | 706 | * DIR: directory to install links to |
704 | */ | 707 | */ |
705 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && argv++); | 708 | use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); |
706 | install_links(busybox, use_symbolic_links, argv[2]); | 709 | install_links(busybox, use_symbolic_links, argv[2]); |
707 | return 0; | 710 | return 0; |
708 | } | 711 | } |
diff --git a/libbb/bb_strtonum.c b/libbb/bb_strtonum.c index c66c774f4..949f26bee 100644 --- a/libbb/bb_strtonum.c +++ b/libbb/bb_strtonum.c | |||
@@ -36,14 +36,14 @@ static unsigned long long ret_ERANGE(void) | |||
36 | return ULLONG_MAX; | 36 | return ULLONG_MAX; |
37 | } | 37 | } |
38 | 38 | ||
39 | static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr) | 39 | static unsigned long long handle_errors(unsigned long long v, char **endp) |
40 | { | 40 | { |
41 | if (endp) *endp = endptr; | 41 | char next_ch = **endp; |
42 | 42 | ||
43 | /* errno is already set to ERANGE by strtoXXX if value overflowed */ | 43 | /* errno is already set to ERANGE by strtoXXX if value overflowed */ |
44 | if (endptr[0]) { | 44 | if (next_ch) { |
45 | /* "1234abcg" or out-of-range? */ | 45 | /* "1234abcg" or out-of-range? */ |
46 | if (isalnum(endptr[0]) || errno) | 46 | if (isalnum(next_ch) || errno) |
47 | return ret_ERANGE(); | 47 | return ret_ERANGE(); |
48 | /* good number, just suspicious terminator */ | 48 | /* good number, just suspicious terminator */ |
49 | errno = EINVAL; | 49 | errno = EINVAL; |
@@ -57,30 +57,37 @@ unsigned long long FAST_FUNC bb_strtoull(const char *arg, char **endp, int base) | |||
57 | unsigned long long v; | 57 | unsigned long long v; |
58 | char *endptr; | 58 | char *endptr; |
59 | 59 | ||
60 | if (!endp) endp = &endptr; | ||
61 | *endp = (char*) arg; | ||
62 | |||
60 | /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ | 63 | /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ |
61 | /* I don't think that this is right. Preventing this... */ | 64 | /* I don't think that this is right. Preventing this... */ |
62 | if (!isalnum(arg[0])) return ret_ERANGE(); | 65 | if (!isalnum(arg[0])) return ret_ERANGE(); |
63 | 66 | ||
64 | /* not 100% correct for lib func, but convenient for the caller */ | 67 | /* not 100% correct for lib func, but convenient for the caller */ |
65 | errno = 0; | 68 | errno = 0; |
66 | v = strtoull(arg, &endptr, base); | 69 | v = strtoull(arg, endp, base); |
67 | return handle_errors(v, endp, endptr); | 70 | return handle_errors(v, endp); |
68 | } | 71 | } |
69 | 72 | ||
70 | long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base) | 73 | long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base) |
71 | { | 74 | { |
72 | unsigned long long v; | 75 | unsigned long long v; |
73 | char *endptr; | 76 | char *endptr; |
77 | char first; | ||
78 | |||
79 | if (!endp) endp = &endptr; | ||
80 | *endp = (char*) arg; | ||
74 | 81 | ||
75 | /* Check for the weird "feature": | 82 | /* Check for the weird "feature": |
76 | * a "-" string is apparently a valid "number" for strto[u]l[l]! | 83 | * a "-" string is apparently a valid "number" for strto[u]l[l]! |
77 | * It returns zero and errno is 0! :( */ | 84 | * It returns zero and errno is 0! :( */ |
78 | char first = (arg[0] != '-' ? arg[0] : arg[1]); | 85 | first = (arg[0] != '-' ? arg[0] : arg[1]); |
79 | if (!isalnum(first)) return ret_ERANGE(); | 86 | if (!isalnum(first)) return ret_ERANGE(); |
80 | 87 | ||
81 | errno = 0; | 88 | errno = 0; |
82 | v = strtoll(arg, &endptr, base); | 89 | v = strtoll(arg, endp, base); |
83 | return handle_errors(v, endp, endptr); | 90 | return handle_errors(v, endp); |
84 | } | 91 | } |
85 | 92 | ||
86 | #if ULONG_MAX != ULLONG_MAX | 93 | #if ULONG_MAX != ULLONG_MAX |
@@ -89,23 +96,30 @@ unsigned long FAST_FUNC bb_strtoul(const char *arg, char **endp, int base) | |||
89 | unsigned long v; | 96 | unsigned long v; |
90 | char *endptr; | 97 | char *endptr; |
91 | 98 | ||
99 | if (!endp) endp = &endptr; | ||
100 | *endp = (char*) arg; | ||
101 | |||
92 | if (!isalnum(arg[0])) return ret_ERANGE(); | 102 | if (!isalnum(arg[0])) return ret_ERANGE(); |
93 | errno = 0; | 103 | errno = 0; |
94 | v = strtoul(arg, &endptr, base); | 104 | v = strtoul(arg, endp, base); |
95 | return handle_errors(v, endp, endptr); | 105 | return handle_errors(v, endp); |
96 | } | 106 | } |
97 | 107 | ||
98 | long FAST_FUNC bb_strtol(const char *arg, char **endp, int base) | 108 | long FAST_FUNC bb_strtol(const char *arg, char **endp, int base) |
99 | { | 109 | { |
100 | long v; | 110 | long v; |
101 | char *endptr; | 111 | char *endptr; |
112 | char first; | ||
102 | 113 | ||
103 | char first = (arg[0] != '-' ? arg[0] : arg[1]); | 114 | if (!endp) endp = &endptr; |
115 | *endp = (char*) arg; | ||
116 | |||
117 | first = (arg[0] != '-' ? arg[0] : arg[1]); | ||
104 | if (!isalnum(first)) return ret_ERANGE(); | 118 | if (!isalnum(first)) return ret_ERANGE(); |
105 | 119 | ||
106 | errno = 0; | 120 | errno = 0; |
107 | v = strtol(arg, &endptr, base); | 121 | v = strtol(arg, endp, base); |
108 | return handle_errors(v, endp, endptr); | 122 | return handle_errors(v, endp); |
109 | } | 123 | } |
110 | #endif | 124 | #endif |
111 | 125 | ||
@@ -115,25 +129,32 @@ unsigned FAST_FUNC bb_strtou(const char *arg, char **endp, int base) | |||
115 | unsigned long v; | 129 | unsigned long v; |
116 | char *endptr; | 130 | char *endptr; |
117 | 131 | ||
132 | if (!endp) endp = &endptr; | ||
133 | *endp = (char*) arg; | ||
134 | |||
118 | if (!isalnum(arg[0])) return ret_ERANGE(); | 135 | if (!isalnum(arg[0])) return ret_ERANGE(); |
119 | errno = 0; | 136 | errno = 0; |
120 | v = strtoul(arg, &endptr, base); | 137 | v = strtoul(arg, endp, base); |
121 | if (v > UINT_MAX) return ret_ERANGE(); | 138 | if (v > UINT_MAX) return ret_ERANGE(); |
122 | return handle_errors(v, endp, endptr); | 139 | return handle_errors(v, endp); |
123 | } | 140 | } |
124 | 141 | ||
125 | int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base) | 142 | int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base) |
126 | { | 143 | { |
127 | long v; | 144 | long v; |
128 | char *endptr; | 145 | char *endptr; |
146 | char first; | ||
147 | |||
148 | if (!endp) endp = &endptr; | ||
149 | *endp = (char*) arg; | ||
129 | 150 | ||
130 | char first = (arg[0] != '-' ? arg[0] : arg[1]); | 151 | first = (arg[0] != '-' ? arg[0] : arg[1]); |
131 | if (!isalnum(first)) return ret_ERANGE(); | 152 | if (!isalnum(first)) return ret_ERANGE(); |
132 | 153 | ||
133 | errno = 0; | 154 | errno = 0; |
134 | v = strtol(arg, &endptr, base); | 155 | v = strtol(arg, endp, base); |
135 | if (v > INT_MAX) return ret_ERANGE(); | 156 | if (v > INT_MAX) return ret_ERANGE(); |
136 | if (v < INT_MIN) return ret_ERANGE(); | 157 | if (v < INT_MIN) return ret_ERANGE(); |
137 | return handle_errors(v, endp, endptr); | 158 | return handle_errors(v, endp); |
138 | } | 159 | } |
139 | #endif | 160 | #endif |
diff --git a/libbb/dump.c b/libbb/dump.c index 919fe135c..7e435643b 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -71,7 +71,8 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
71 | * skip any special chars -- save precision in | 71 | * skip any special chars -- save precision in |
72 | * case it's a %s format. | 72 | * case it's a %s format. |
73 | */ | 73 | */ |
74 | while (strchr(index_str + 1, *++fmt)); | 74 | while (strchr(index_str + 1, *++fmt)) |
75 | continue; | ||
75 | if (*fmt == '.' && isdigit(*++fmt)) { | 76 | if (*fmt == '.' && isdigit(*++fmt)) { |
76 | prec = atoi(fmt); | 77 | prec = atoi(fmt); |
77 | while (isdigit(*++fmt)) | 78 | while (isdigit(*++fmt)) |
@@ -99,8 +100,8 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
99 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | 100 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) |
100 | { | 101 | { |
101 | enum { NOTOKAY, USEBCNT, USEPREC } sokay; | 102 | enum { NOTOKAY, USEBCNT, USEPREC } sokay; |
102 | PR *pr; | ||
103 | FU *fu; | 103 | FU *fu; |
104 | PR *pr; | ||
104 | char *p1, *p2, *p3; | 105 | char *p1, *p2, *p3; |
105 | char savech, *fmtp; | 106 | char savech, *fmtp; |
106 | const char *byte_count_str; | 107 | const char *byte_count_str; |
@@ -292,16 +293,18 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
292 | * interprets any data at all, and has no iteration count, | 293 | * interprets any data at all, and has no iteration count, |
293 | * repeat it as necessary. | 294 | * repeat it as necessary. |
294 | * | 295 | * |
295 | * if, rep count is greater than 1, no trailing whitespace | 296 | * if rep count is greater than 1, no trailing whitespace |
296 | * gets output from the last iteration of the format unit. | 297 | * gets output from the last iteration of the format unit. |
297 | */ | 298 | */ |
298 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 299 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
299 | if (!fu->nextfu && fs->bcnt < dumper->blocksize | 300 | if (!fu->nextfu |
300 | && !(fu->flags & F_SETREP) && fu->bcnt | 301 | && fs->bcnt < dumper->blocksize |
302 | && !(fu->flags & F_SETREP) | ||
303 | && fu->bcnt | ||
301 | ) { | 304 | ) { |
302 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; | 305 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; |
303 | } | 306 | } |
304 | if (fu->reps > 1) { | 307 | if (fu->reps > 1 && fu->nextpr) { |
305 | for (pr = fu->nextpr;; pr = pr->nextpr) | 308 | for (pr = fu->nextpr;; pr = pr->nextpr) |
306 | if (!pr->nextpr) | 309 | if (!pr->nextpr) |
307 | break; | 310 | break; |
@@ -721,7 +724,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
721 | p = fmt; | 724 | p = fmt; |
722 | for (;;) { | 725 | for (;;) { |
723 | p = skip_whitespace(p); | 726 | p = skip_whitespace(p); |
724 | if (!*p) { | 727 | if (*p == '\0') { |
725 | break; | 728 | break; |
726 | } | 729 | } |
727 | 730 | ||
@@ -749,7 +752,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
749 | 752 | ||
750 | /* skip slash and trailing white space */ | 753 | /* skip slash and trailing white space */ |
751 | if (*p == '/') { | 754 | if (*p == '/') { |
752 | p = skip_whitespace(++p); | 755 | p = skip_whitespace(p + 1); |
753 | } | 756 | } |
754 | 757 | ||
755 | /* byte count */ | 758 | /* byte count */ |
@@ -763,7 +766,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
763 | } | 766 | } |
764 | tfu->bcnt = atoi(savep); | 767 | tfu->bcnt = atoi(savep); |
765 | /* skip trailing white space */ | 768 | /* skip trailing white space */ |
766 | p = skip_whitespace(++p); | 769 | p = skip_whitespace(p + 1); |
767 | } | 770 | } |
768 | 771 | ||
769 | /* format */ | 772 | /* format */ |
@@ -771,7 +774,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
771 | bb_error_msg_and_die("bad format {%s}", fmt); | 774 | bb_error_msg_and_die("bad format {%s}", fmt); |
772 | } | 775 | } |
773 | for (savep = ++p; *p != '"';) { | 776 | for (savep = ++p; *p != '"';) { |
774 | if (*p++ == 0) { | 777 | if (*p++ == '\0') { |
775 | bb_error_msg_and_die("bad format {%s}", fmt); | 778 | bb_error_msg_and_die("bad format {%s}", fmt); |
776 | } | 779 | } |
777 | } | 780 | } |
@@ -782,7 +785,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
782 | 785 | ||
783 | /* alphabetic escape sequences have to be done in place */ | 786 | /* alphabetic escape sequences have to be done in place */ |
784 | for (p2 = p1;; ++p1, ++p2) { | 787 | for (p2 = p1;; ++p1, ++p2) { |
785 | if (!*p1) { | 788 | if (*p1 == '\0') { |
786 | *p2 = *p1; | 789 | *p2 = *p1; |
787 | break; | 790 | break; |
788 | } | 791 | } |
diff --git a/libbb/find_mount_point.c b/libbb/find_mount_point.c index 56637ad92..9676b5f52 100644 --- a/libbb/find_mount_point.c +++ b/libbb/find_mount_point.c | |||
@@ -30,7 +30,8 @@ struct mntent* FAST_FUNC find_mount_point(const char *name, int subdir_too) | |||
30 | 30 | ||
31 | devno_of_name = s.st_dev; | 31 | devno_of_name = s.st_dev; |
32 | block_dev = 0; | 32 | block_dev = 0; |
33 | if (S_ISBLK(s.st_mode)) { | 33 | /* Why S_ISCHR? - UBI volumes use char devices, not block */ |
34 | if (S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode)) { | ||
34 | devno_of_name = s.st_rdev; | 35 | devno_of_name = s.st_rdev; |
35 | block_dev = 1; | 36 | block_dev = 1; |
36 | } | 37 | } |
diff --git a/libbb/isdirectory.c b/libbb/isdirectory.c index 9861be6f8..ba6c52ce8 100644 --- a/libbb/isdirectory.c +++ b/libbb/isdirectory.c | |||
@@ -15,22 +15,17 @@ | |||
15 | * Return TRUE if fileName is a directory. | 15 | * Return TRUE if fileName is a directory. |
16 | * Nonexistent files return FALSE. | 16 | * Nonexistent files return FALSE. |
17 | */ | 17 | */ |
18 | int FAST_FUNC is_directory(const char *fileName, int followLinks, struct stat *statBuf) | 18 | int FAST_FUNC is_directory(const char *fileName, int followLinks) |
19 | { | 19 | { |
20 | int status; | 20 | int status; |
21 | struct stat astatBuf; | 21 | struct stat statBuf; |
22 | |||
23 | if (statBuf == NULL) { | ||
24 | /* use auto stack buffer */ | ||
25 | statBuf = &astatBuf; | ||
26 | } | ||
27 | 22 | ||
28 | if (followLinks) | 23 | if (followLinks) |
29 | status = stat(fileName, statBuf); | 24 | status = stat(fileName, &statBuf); |
30 | else | 25 | else |
31 | status = lstat(fileName, statBuf); | 26 | status = lstat(fileName, &statBuf); |
32 | 27 | ||
33 | status = (status == 0 && S_ISDIR(statBuf->st_mode)); | 28 | status = (status == 0 && S_ISDIR(statBuf.st_mode)); |
34 | 29 | ||
35 | return status; | 30 | return status; |
36 | } | 31 | } |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index c89c829ed..78244c395 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -2221,14 +2221,17 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2221 | #define command command_must_not_be_used | 2221 | #define command command_must_not_be_used |
2222 | 2222 | ||
2223 | new_settings = initial_settings; | 2223 | new_settings = initial_settings; |
2224 | new_settings.c_lflag &= ~ICANON; /* unbuffered input */ | 2224 | /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */ |
2225 | /* Turn off echoing and CTRL-C, so we can trap it */ | 2225 | /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ |
2226 | new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); | 2226 | /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ |
2227 | /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ | 2227 | new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); |
2228 | /* reads would block only if < 1 char is available */ | ||
2228 | new_settings.c_cc[VMIN] = 1; | 2229 | new_settings.c_cc[VMIN] = 1; |
2230 | /* no timeout (reads block forever) */ | ||
2229 | new_settings.c_cc[VTIME] = 0; | 2231 | new_settings.c_cc[VTIME] = 0; |
2230 | /* Turn off CTRL-C, so we can trap it */ | 2232 | /* Should be not needed if ISIG is off: */ |
2231 | new_settings.c_cc[VINTR] = _POSIX_VDISABLE; | 2233 | /* Turn off CTRL-C */ |
2234 | /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */ | ||
2232 | tcsetattr_stdin_TCSANOW(&new_settings); | 2235 | tcsetattr_stdin_TCSANOW(&new_settings); |
2233 | 2236 | ||
2234 | #if ENABLE_USERNAME_OR_HOMEDIR | 2237 | #if ENABLE_USERNAME_OR_HOMEDIR |
diff --git a/libbb/parse_config.c b/libbb/parse_config.c index cf5ba4deb..1590d9a4c 100644 --- a/libbb/parse_config.c +++ b/libbb/parse_config.c | |||
@@ -204,7 +204,7 @@ int FAST_FUNC config_read(parser_t *parser, char **tokens, unsigned flags, const | |||
204 | line += strcspn(line, delims[0] ? delims : delims + 1); | 204 | line += strcspn(line, delims[0] ? delims : delims + 1); |
205 | } else { | 205 | } else { |
206 | /* Combining, find comment char if any */ | 206 | /* Combining, find comment char if any */ |
207 | line = strchrnul(line, delims[0]); | 207 | line = strchrnul(line, PARSE_EOL_COMMENTS ? delims[0] : '\0'); |
208 | 208 | ||
209 | /* Trim any extra delimiters from the end */ | 209 | /* Trim any extra delimiters from the end */ |
210 | if (flags & PARSE_TRIM) { | 210 | if (flags & PARSE_TRIM) { |
diff --git a/libbb/procps.c b/libbb/procps.c index 39ddd2c12..dbae46e33 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -128,10 +128,11 @@ static unsigned long fast_strtoul_16(char **endptr) | |||
128 | char *str = *endptr; | 128 | char *str = *endptr; |
129 | unsigned long n = 0; | 129 | unsigned long n = 0; |
130 | 130 | ||
131 | while ((c = *str++) != ' ') { | 131 | /* Need to stop on both ' ' and '\n' */ |
132 | while ((c = *str++) > ' ') { | ||
132 | c = ((c|0x20) - '0'); | 133 | c = ((c|0x20) - '0'); |
133 | if (c > 9) | 134 | if (c > 9) |
134 | // c = c + '0' - 'a' + 10: | 135 | /* c = c + '0' - 'a' + 10: */ |
135 | c = c - ('a' - '0' - 10); | 136 | c = c - ('a' - '0' - 10); |
136 | n = n*16 + c; | 137 | n = n*16 + c; |
137 | } | 138 | } |
@@ -144,11 +145,12 @@ static unsigned long fast_strtoul_16(char **endptr) | |||
144 | /* We cut a lot of corners here for speed */ | 145 | /* We cut a lot of corners here for speed */ |
145 | static unsigned long fast_strtoul_10(char **endptr) | 146 | static unsigned long fast_strtoul_10(char **endptr) |
146 | { | 147 | { |
147 | char c; | 148 | unsigned char c; |
148 | char *str = *endptr; | 149 | char *str = *endptr; |
149 | unsigned long n = *str - '0'; | 150 | unsigned long n = *str - '0'; |
150 | 151 | ||
151 | while ((c = *++str) != ' ') | 152 | /* Need to stop on both ' ' and '\n' */ |
153 | while ((c = *++str) > ' ') | ||
152 | n = n*10 + (c - '0'); | 154 | n = n*10 + (c - '0'); |
153 | 155 | ||
154 | *endptr = str + 1; /* We skip trailing space! */ | 156 | *endptr = str + 1; /* We skip trailing space! */ |
@@ -199,7 +201,7 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
199 | memset(&currec, 0, sizeof(currec)); | 201 | memset(&currec, 0, sizeof(currec)); |
200 | while (fgets(buf, PROCPS_BUFSIZE, file)) { | 202 | while (fgets(buf, PROCPS_BUFSIZE, file)) { |
201 | // Each mapping datum has this form: | 203 | // Each mapping datum has this form: |
202 | // f7d29000-f7d39000 rw-s ADR M:m OFS FILE | 204 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME |
203 | // Size: nnn kB | 205 | // Size: nnn kB |
204 | // Rss: nnn kB | 206 | // Rss: nnn kB |
205 | // ..... | 207 | // ..... |
@@ -224,7 +226,7 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
224 | tp = strchr(buf, '-'); | 226 | tp = strchr(buf, '-'); |
225 | if (tp) { | 227 | if (tp) { |
226 | // We reached next mapping - the line of this form: | 228 | // We reached next mapping - the line of this form: |
227 | // f7d29000-f7d39000 rw-s ADR M:m OFS FILE | 229 | // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME |
228 | 230 | ||
229 | if (cb) { | 231 | if (cb) { |
230 | /* If we have a previous record, there's nothing more | 232 | /* If we have a previous record, there's nothing more |
@@ -243,7 +245,7 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
243 | 245 | ||
244 | strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1); | 246 | strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1); |
245 | 247 | ||
246 | // skipping "rw-s ADR M:m OFS " | 248 | // skipping "rw-s FILEOFS M:m INODE " |
247 | tp = skip_whitespace(skip_fields(tp, 4)); | 249 | tp = skip_whitespace(skip_fields(tp, 4)); |
248 | // filter out /dev/something (something != zero) | 250 | // filter out /dev/something (something != zero) |
249 | if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { | 251 | if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { |
diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 0bbf7802a..5ed6e3632 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c | |||
@@ -8,16 +8,6 @@ | |||
8 | */ | 8 | */ |
9 | #include "libbb.h" | 9 | #include "libbb.h" |
10 | 10 | ||
11 | #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ | ||
12 | || ENABLE_FEATURE_SEAMLESS_BZ2 \ | ||
13 | || ENABLE_FEATURE_SEAMLESS_GZ \ | ||
14 | /* || ENABLE_FEATURE_SEAMLESS_Z */ \ | ||
15 | ) | ||
16 | |||
17 | #if ZIPPED | ||
18 | # include "bb_archive.h" | ||
19 | #endif | ||
20 | |||
21 | 11 | ||
22 | /* Suppose that you are a shell. You start child processes. | 12 | /* Suppose that you are a shell. You start child processes. |
23 | * They work and eventually exit. You want to get user input. | 13 | * They work and eventually exit. You want to get user input. |
@@ -244,132 +234,3 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) | |||
244 | bb_perror_msg_and_die("can't read '%s'", filename); | 234 | bb_perror_msg_and_die("can't read '%s'", filename); |
245 | return buf; | 235 | return buf; |
246 | } | 236 | } |
247 | |||
248 | /* Used by e.g. rpm which gives us a fd without filename, | ||
249 | * thus we can't guess the format from filename's extension. | ||
250 | */ | ||
251 | #if ZIPPED | ||
252 | void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/) | ||
253 | { | ||
254 | const int fail_if_not_detected = 1; | ||
255 | union { | ||
256 | uint8_t b[4]; | ||
257 | uint16_t b16[2]; | ||
258 | uint32_t b32[1]; | ||
259 | } magic; | ||
260 | int offset = -2; | ||
261 | # if BB_MMU | ||
262 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); | ||
263 | enum { xformer_prog = 0 }; | ||
264 | # else | ||
265 | enum { xformer = 0 }; | ||
266 | const char *xformer_prog; | ||
267 | # endif | ||
268 | |||
269 | /* .gz and .bz2 both have 2-byte signature, and their | ||
270 | * unpack_XXX_stream wants this header skipped. */ | ||
271 | xread(fd, magic.b16, sizeof(magic.b16[0])); | ||
272 | if (ENABLE_FEATURE_SEAMLESS_GZ | ||
273 | && magic.b16[0] == GZIP_MAGIC | ||
274 | ) { | ||
275 | # if BB_MMU | ||
276 | xformer = unpack_gz_stream; | ||
277 | # else | ||
278 | xformer_prog = "gunzip"; | ||
279 | # endif | ||
280 | goto found_magic; | ||
281 | } | ||
282 | if (ENABLE_FEATURE_SEAMLESS_BZ2 | ||
283 | && magic.b16[0] == BZIP2_MAGIC | ||
284 | ) { | ||
285 | # if BB_MMU | ||
286 | xformer = unpack_bz2_stream; | ||
287 | # else | ||
288 | xformer_prog = "bunzip2"; | ||
289 | # endif | ||
290 | goto found_magic; | ||
291 | } | ||
292 | if (ENABLE_FEATURE_SEAMLESS_XZ | ||
293 | && magic.b16[0] == XZ_MAGIC1 | ||
294 | ) { | ||
295 | offset = -6; | ||
296 | xread(fd, magic.b32, sizeof(magic.b32[0])); | ||
297 | if (magic.b32[0] == XZ_MAGIC2) { | ||
298 | # if BB_MMU | ||
299 | xformer = unpack_xz_stream; | ||
300 | /* unpack_xz_stream wants fd at position 6, no need to seek */ | ||
301 | //xlseek(fd, offset, SEEK_CUR); | ||
302 | # else | ||
303 | xformer_prog = "unxz"; | ||
304 | # endif | ||
305 | goto found_magic; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | /* No known magic seen */ | ||
310 | if (fail_if_not_detected) | ||
311 | bb_error_msg_and_die("no gzip" | ||
312 | IF_FEATURE_SEAMLESS_BZ2("/bzip2") | ||
313 | IF_FEATURE_SEAMLESS_XZ("/xz") | ||
314 | " magic"); | ||
315 | xlseek(fd, offset, SEEK_CUR); | ||
316 | return; | ||
317 | |||
318 | found_magic: | ||
319 | # if !BB_MMU | ||
320 | /* NOMMU version of open_transformer execs | ||
321 | * an external unzipper that wants | ||
322 | * file position at the start of the file */ | ||
323 | xlseek(fd, offset, SEEK_CUR); | ||
324 | # endif | ||
325 | open_transformer(fd, xformer, xformer_prog); | ||
326 | } | ||
327 | #endif /* ZIPPED */ | ||
328 | |||
329 | int FAST_FUNC open_zipped(const char *fname) | ||
330 | { | ||
331 | #if !ZIPPED | ||
332 | return open(fname, O_RDONLY); | ||
333 | #else | ||
334 | char *sfx; | ||
335 | int fd; | ||
336 | |||
337 | fd = open(fname, O_RDONLY); | ||
338 | if (fd < 0) | ||
339 | return fd; | ||
340 | |||
341 | sfx = strrchr(fname, '.'); | ||
342 | if (sfx) { | ||
343 | sfx++; | ||
344 | if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0) | ||
345 | /* .lzma has no header/signature, just trust it */ | ||
346 | open_transformer(fd, unpack_lzma_stream, "unlzma"); | ||
347 | else | ||
348 | if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0) | ||
349 | || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0) | ||
350 | || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0) | ||
351 | ) { | ||
352 | setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | return fd; | ||
357 | #endif | ||
358 | } | ||
359 | |||
360 | void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) | ||
361 | { | ||
362 | int fd; | ||
363 | char *image; | ||
364 | |||
365 | fd = open_zipped(fname); | ||
366 | if (fd < 0) | ||
367 | return NULL; | ||
368 | |||
369 | image = xmalloc_read(fd, maxsz_p); | ||
370 | if (!image) | ||
371 | bb_perror_msg("read error from '%s'", fname); | ||
372 | close(fd); | ||
373 | |||
374 | return image; | ||
375 | } | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 5d8056bd6..6611dabfa 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -256,11 +256,19 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char **argv) | |||
256 | if (!(flags & DAEMON_ONLY_SANITIZE)) { | 256 | if (!(flags & DAEMON_ONLY_SANITIZE)) { |
257 | if (fork_or_rexec(argv)) | 257 | if (fork_or_rexec(argv)) |
258 | exit(EXIT_SUCCESS); /* parent */ | 258 | exit(EXIT_SUCCESS); /* parent */ |
259 | /* if daemonizing, make sure we detach from stdio & ctty */ | 259 | /* if daemonizing, detach from stdio & ctty */ |
260 | setsid(); | 260 | setsid(); |
261 | dup2(fd, 0); | 261 | dup2(fd, 0); |
262 | dup2(fd, 1); | 262 | dup2(fd, 1); |
263 | dup2(fd, 2); | 263 | dup2(fd, 2); |
264 | if (flags & DAEMON_DOUBLE_FORK) { | ||
265 | /* On Linux, session leader can acquire ctty | ||
266 | * unknowingly, by opening a tty. | ||
267 | * Prevent this: stop being a session leader. | ||
268 | */ | ||
269 | if (fork_or_rexec(argv)) | ||
270 | exit(EXIT_SUCCESS); /* parent */ | ||
271 | } | ||
264 | } | 272 | } |
265 | while (fd > 2) { | 273 | while (fd > 2) { |
266 | close(fd--); | 274 | close(fd--); |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 4b7c110d3..1c8bb2b73 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -322,26 +322,28 @@ len_and_sockaddr* FAST_FUNC xdotted2sockaddr(const char *host, int port) | |||
322 | return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); | 322 | return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); |
323 | } | 323 | } |
324 | 324 | ||
325 | #undef xsocket_type | 325 | int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, int family, int sock_type) |
326 | int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, IF_FEATURE_IPV6(int family,) int sock_type) | ||
327 | { | 326 | { |
328 | IF_NOT_FEATURE_IPV6(enum { family = AF_INET };) | ||
329 | len_and_sockaddr *lsa; | 327 | len_and_sockaddr *lsa; |
330 | int fd; | 328 | int fd; |
331 | int len; | 329 | int len; |
332 | 330 | ||
333 | #if ENABLE_FEATURE_IPV6 | ||
334 | if (family == AF_UNSPEC) { | 331 | if (family == AF_UNSPEC) { |
332 | #if ENABLE_FEATURE_IPV6 | ||
335 | fd = socket(AF_INET6, sock_type, 0); | 333 | fd = socket(AF_INET6, sock_type, 0); |
336 | if (fd >= 0) { | 334 | if (fd >= 0) { |
337 | family = AF_INET6; | 335 | family = AF_INET6; |
338 | goto done; | 336 | goto done; |
339 | } | 337 | } |
338 | #endif | ||
340 | family = AF_INET; | 339 | family = AF_INET; |
341 | } | 340 | } |
342 | #endif | 341 | |
343 | fd = xsocket(family, sock_type, 0); | 342 | fd = xsocket(family, sock_type, 0); |
343 | |||
344 | len = sizeof(struct sockaddr_in); | 344 | len = sizeof(struct sockaddr_in); |
345 | if (family == AF_UNIX) | ||
346 | len = sizeof(struct sockaddr_un); | ||
345 | #if ENABLE_FEATURE_IPV6 | 347 | #if ENABLE_FEATURE_IPV6 |
346 | if (family == AF_INET6) { | 348 | if (family == AF_INET6) { |
347 | done: | 349 | done: |
@@ -357,7 +359,7 @@ int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, IF_FEATURE_IPV6(int family,) | |||
357 | 359 | ||
358 | int FAST_FUNC xsocket_stream(len_and_sockaddr **lsap) | 360 | int FAST_FUNC xsocket_stream(len_and_sockaddr **lsap) |
359 | { | 361 | { |
360 | return xsocket_type(lsap, IF_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM); | 362 | return xsocket_type(lsap, AF_UNSPEC, SOCK_STREAM); |
361 | } | 363 | } |
362 | 364 | ||
363 | static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) | 365 | static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) |
@@ -370,7 +372,7 @@ static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) | |||
370 | /* user specified bind addr dictates family */ | 372 | /* user specified bind addr dictates family */ |
371 | fd = xsocket(lsa->u.sa.sa_family, sock_type, 0); | 373 | fd = xsocket(lsa->u.sa.sa_family, sock_type, 0); |
372 | } else { | 374 | } else { |
373 | fd = xsocket_type(&lsa, IF_FEATURE_IPV6(AF_UNSPEC,) sock_type); | 375 | fd = xsocket_type(&lsa, AF_UNSPEC, sock_type); |
374 | set_nport(&lsa->u.sa, htons(port)); | 376 | set_nport(&lsa->u.sa, htons(port)); |
375 | } | 377 | } |
376 | setsockopt_reuseaddr(fd); | 378 | setsockopt_reuseaddr(fd); |
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 8a6d7e1d1..70d3fc96c 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c | |||
@@ -376,6 +376,7 @@ void FAST_FUNC xchroot(const char *path) | |||
376 | { | 376 | { |
377 | if (chroot(path)) | 377 | if (chroot(path)) |
378 | bb_perror_msg_and_die("can't change root directory to %s", path); | 378 | bb_perror_msg_and_die("can't change root directory to %s", path); |
379 | xchdir("/"); | ||
379 | } | 380 | } |
380 | 381 | ||
381 | // Print a warning message if opendir() fails, but don't die. | 382 | // Print a warning message if opendir() fails, but don't die. |