diff options
author | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-10-13 14:45:51 +0100 |
commit | 8e509f11bceeec419abc718300bef7422d1fee4c (patch) | |
tree | fdfbc752ad94102e3613a5d7254f14a93eaf7f56 /libbb | |
parent | 420f5edfe7676fe6e7cddbbf15c04649d096e422 (diff) | |
parent | 4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 (diff) | |
download | busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.gz busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.tar.bz2 busybox-w32-8e509f11bceeec419abc718300bef7422d1fee4c.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/auto_string.c | 23 | ||||
-rw-r--r-- | libbb/bb_askpass.c | 6 | ||||
-rw-r--r-- | libbb/bbunit.c | 31 | ||||
-rw-r--r-- | libbb/compare_string_array.c | 59 | ||||
-rw-r--r-- | libbb/fflush_stdout_and_exit.c | 13 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 16 | ||||
-rw-r--r-- | libbb/human_readable.c | 9 | ||||
-rw-r--r-- | libbb/messages.c | 2 | ||||
-rw-r--r-- | libbb/parse_mode.c | 16 | ||||
-rw-r--r-- | libbb/printable_string.c | 10 | ||||
-rw-r--r-- | libbb/procps.c | 4 | ||||
-rw-r--r-- | libbb/udp_io.c | 4 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 39 | ||||
-rw-r--r-- | libbb/xconnect.c | 25 | ||||
-rw-r--r-- | libbb/xfunc_die.c | 26 |
15 files changed, 162 insertions, 121 deletions
diff --git a/libbb/auto_string.c b/libbb/auto_string.c new file mode 100644 index 000000000..ae940069a --- /dev/null +++ b/libbb/auto_string.c | |||
@@ -0,0 +1,23 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2015 Denys Vlasenko | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //kbuild:lib-y += auto_string.o | ||
10 | |||
11 | #include "libbb.h" | ||
12 | |||
13 | char* FAST_FUNC auto_string(char *str) | ||
14 | { | ||
15 | static char *saved[4]; | ||
16 | static uint8_t cur_saved; /* = 0 */ | ||
17 | |||
18 | free(saved[cur_saved]); | ||
19 | saved[cur_saved] = str; | ||
20 | cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); | ||
21 | |||
22 | return str; | ||
23 | } | ||
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 1927ba9e9..c2580b9eb 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Ask for a password | 3 | * Ask for a password |
4 | * I use a static buffer in this function. Plan accordingly. | ||
5 | * | 4 | * |
6 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> | 5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
7 | * | 6 | * |
@@ -23,8 +22,8 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
23 | { | 22 | { |
24 | /* Was static char[BIGNUM] */ | 23 | /* Was static char[BIGNUM] */ |
25 | enum { sizeof_passwd = 128 }; | 24 | enum { sizeof_passwd = 128 }; |
26 | static char *passwd; | ||
27 | 25 | ||
26 | char *passwd; | ||
28 | char *ret; | 27 | char *ret; |
29 | int i; | 28 | int i; |
30 | struct sigaction sa, oldsa; | 29 | struct sigaction sa, oldsa; |
@@ -62,8 +61,7 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) | |||
62 | alarm(timeout); | 61 | alarm(timeout); |
63 | } | 62 | } |
64 | 63 | ||
65 | if (!passwd) | 64 | passwd = auto_string(xmalloc(sizeof_passwd)); |
66 | passwd = xmalloc(sizeof_passwd); | ||
67 | ret = passwd; | 65 | ret = passwd; |
68 | i = 0; | 66 | i = 0; |
69 | while (1) { | 67 | while (1) { |
diff --git a/libbb/bbunit.c b/libbb/bbunit.c index 4c692d59f..db67b1081 100644 --- a/libbb/bbunit.c +++ b/libbb/bbunit.c | |||
@@ -17,8 +17,6 @@ | |||
17 | 17 | ||
18 | #include "libbb.h" | 18 | #include "libbb.h" |
19 | 19 | ||
20 | #define WANT_TIMING 0 | ||
21 | |||
22 | static llist_t *tests = NULL; | 20 | static llist_t *tests = NULL; |
23 | static unsigned tests_registered = 0; | 21 | static unsigned tests_registered = 0; |
24 | static int test_retval; | 22 | static int test_retval; |
@@ -34,57 +32,34 @@ void bbunit_settestfailed(void) | |||
34 | test_retval = -1; | 32 | test_retval = -1; |
35 | } | 33 | } |
36 | 34 | ||
37 | #if WANT_TIMING | ||
38 | static void timeval_diff(struct timeval* res, | ||
39 | const struct timeval* x, | ||
40 | const struct timeval* y) | ||
41 | { | ||
42 | long udiff = x->tv_usec - y->tv_usec; | ||
43 | |||
44 | res->tv_sec = x->tv_sec - y->tv_sec - (udiff < 0); | ||
45 | res->tv_usec = (udiff >= 0 ? udiff : udiff + 1000000); | ||
46 | } | ||
47 | #endif | ||
48 | |||
49 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; | 35 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; |
50 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | 36 | int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) |
51 | { | 37 | { |
52 | unsigned tests_run = 0; | 38 | unsigned tests_run = 0; |
53 | unsigned tests_failed = 0; | 39 | unsigned tests_failed = 0; |
54 | #if WANT_TIMING | ||
55 | struct timeval begin; | ||
56 | struct timeval end; | ||
57 | struct timeval time_spent; | ||
58 | gettimeofday(&begin, NULL); | ||
59 | #endif | ||
60 | 40 | ||
61 | bb_error_msg("Running %d test(s)...", tests_registered); | 41 | bb_error_msg("Running %d test(s)...", tests_registered); |
62 | for (;;) { | 42 | for (;;) { |
63 | struct bbunit_listelem* el = llist_pop(&tests); | 43 | struct bbunit_listelem* el = llist_pop(&tests); |
64 | if (!el) | 44 | if (!el) |
65 | break; | 45 | break; |
46 | |||
66 | bb_error_msg("Case: [%s]", el->name); | 47 | bb_error_msg("Case: [%s]", el->name); |
67 | test_retval = 0; | 48 | test_retval = 0; |
68 | el->testfunc(); | 49 | el->testfunc(); |
50 | |||
69 | if (test_retval < 0) { | 51 | if (test_retval < 0) { |
70 | bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); | 52 | bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); |
71 | tests_failed++; | 53 | tests_failed++; |
72 | } | 54 | } |
73 | tests_run++; | 55 | tests_run++; |
74 | el = el->next; | ||
75 | } | 56 | } |
76 | 57 | ||
77 | #if WANT_TIMING | ||
78 | gettimeofday(&end, NULL); | ||
79 | timeval_diff(&time_spent, &end, &begin); | ||
80 | bb_error_msg("Elapsed time %u.%06u seconds", | ||
81 | (int)time_spent.tv_sec, | ||
82 | (int)time_spent.tv_usec); | ||
83 | #endif | ||
84 | if (tests_failed > 0) { | 58 | if (tests_failed > 0) { |
85 | bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); | 59 | bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); |
86 | return EXIT_FAILURE; | 60 | return EXIT_FAILURE; |
87 | } | 61 | } |
62 | |||
88 | bb_error_msg("All tests passed"); | 63 | bb_error_msg("All tests passed"); |
89 | return EXIT_SUCCESS; | 64 | return EXIT_SUCCESS; |
90 | } | 65 | } |
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index e24815a03..2f51237a3 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c | |||
@@ -5,6 +5,11 @@ | |||
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | 7 | ||
8 | /* | ||
9 | * Return NULL if string is not prefixed with key. Return pointer to the | ||
10 | * first character in string after the prefix key. If key is an empty string, | ||
11 | * return pointer to the beginning of string. | ||
12 | */ | ||
8 | char* FAST_FUNC is_prefixed_with(const char *string, const char *key) | 13 | char* FAST_FUNC is_prefixed_with(const char *string, const char *key) |
9 | { | 14 | { |
10 | #if 0 /* Two passes over key - probably slower */ | 15 | #if 0 /* Two passes over key - probably slower */ |
@@ -23,6 +28,26 @@ char* FAST_FUNC is_prefixed_with(const char *string, const char *key) | |||
23 | #endif | 28 | #endif |
24 | } | 29 | } |
25 | 30 | ||
31 | /* | ||
32 | * Return NULL if string is not suffixed with key. Return pointer to the | ||
33 | * beginning of prefix key in string. If key is an empty string return pointer | ||
34 | * to the end of string. | ||
35 | */ | ||
36 | char* FAST_FUNC is_suffixed_with(const char *string, const char *key) | ||
37 | { | ||
38 | size_t key_len = strlen(key); | ||
39 | ssize_t len_diff = strlen(string) - key_len; | ||
40 | |||
41 | if (len_diff >= 0) { | ||
42 | string += len_diff; | ||
43 | if (strcmp(string, key) == 0) { | ||
44 | return (char*)string; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | |||
26 | /* returns the array index of the string */ | 51 | /* returns the array index of the string */ |
27 | /* (index of first match is returned, or -1) */ | 52 | /* (index of first match is returned, or -1) */ |
28 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) | 53 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) |
@@ -110,3 +135,37 @@ smallint FAST_FUNC yesno(const char *str) | |||
110 | return ret / 3; | 135 | return ret / 3; |
111 | } | 136 | } |
112 | #endif | 137 | #endif |
138 | |||
139 | #if ENABLE_UNIT_TEST | ||
140 | |||
141 | BBUNIT_DEFINE_TEST(is_prefixed_with) | ||
142 | { | ||
143 | BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo")); | ||
144 | BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo ")); | ||
145 | BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo")); | ||
146 | BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", "")); | ||
147 | BBUNIT_ASSERT_STREQ("", is_prefixed_with("", "")); | ||
148 | |||
149 | BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo")); | ||
150 | BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar")); | ||
151 | BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo")); | ||
152 | |||
153 | BBUNIT_ENDTEST; | ||
154 | } | ||
155 | |||
156 | BBUNIT_DEFINE_TEST(is_suffixed_with) | ||
157 | { | ||
158 | BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar")); | ||
159 | BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo")); | ||
160 | BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", "")); | ||
161 | BBUNIT_ASSERT_STREQ("", is_suffixed_with("", "")); | ||
162 | BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo")); | ||
163 | |||
164 | BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo")); | ||
165 | BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar")); | ||
166 | BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo")); | ||
167 | |||
168 | BBUNIT_ENDTEST; | ||
169 | } | ||
170 | |||
171 | #endif /* ENABLE_UNIT_TEST */ | ||
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index 9ad5dbf96..b4bed865f 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c | |||
@@ -15,15 +15,10 @@ | |||
15 | 15 | ||
16 | void FAST_FUNC fflush_stdout_and_exit(int retval) | 16 | void FAST_FUNC fflush_stdout_and_exit(int retval) |
17 | { | 17 | { |
18 | xfunc_error_retval = retval; | ||
18 | if (fflush(stdout)) | 19 | if (fflush(stdout)) |
19 | bb_perror_msg_and_die(bb_msg_standard_output); | 20 | bb_perror_msg_and_die(bb_msg_standard_output); |
20 | 21 | /* In case we are in NOFORK applet. Do not exit() directly, | |
21 | if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { | 22 | * but use xfunc_die() */ |
22 | /* We are in NOFORK applet. Do not exit() directly, | 23 | xfunc_die(); |
23 | * but use xfunc_die() */ | ||
24 | xfunc_error_retval = retval; | ||
25 | xfunc_die(); | ||
26 | } | ||
27 | |||
28 | exit(retval); | ||
29 | } | 24 | } |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 1f63ccdee..d08c6b2f7 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -137,7 +137,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
137 | #if MD5_SMALL > 0 | 137 | #if MD5_SMALL > 0 |
138 | /* Before we start, one word to the strange constants. | 138 | /* Before we start, one word to the strange constants. |
139 | They are defined in RFC 1321 as | 139 | They are defined in RFC 1321 as |
140 | T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 | 140 | T[i] = (int)(2^32 * fabs(sin(i))), i=1..64 |
141 | */ | 141 | */ |
142 | static const uint32_t C_array[] = { | 142 | static const uint32_t C_array[] = { |
143 | /* round 1 */ | 143 | /* round 1 */ |
@@ -213,7 +213,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
213 | case 2: | 213 | case 2: |
214 | temp += FH(B, C, D); | 214 | temp += FH(B, C, D); |
215 | break; | 215 | break; |
216 | case 3: | 216 | default: /* case 3 */ |
217 | temp += FI(B, C, D); | 217 | temp += FI(B, C, D); |
218 | } | 218 | } |
219 | temp += words[(int) (*pp++)] + *pc++; | 219 | temp += words[(int) (*pp++)] + *pc++; |
@@ -277,10 +277,6 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
277 | 277 | ||
278 | #else /* MD5_SMALL == 0 or 1 */ | 278 | #else /* MD5_SMALL == 0 or 1 */ |
279 | 279 | ||
280 | uint32_t A_save = A; | ||
281 | uint32_t B_save = B; | ||
282 | uint32_t C_save = C; | ||
283 | uint32_t D_save = D; | ||
284 | # if MD5_SMALL == 1 | 280 | # if MD5_SMALL == 1 |
285 | const uint32_t *pc; | 281 | const uint32_t *pc; |
286 | const char *pp; | 282 | const char *pp; |
@@ -425,10 +421,10 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) | |||
425 | # undef OP | 421 | # undef OP |
426 | # endif | 422 | # endif |
427 | /* Add checksum to the starting values */ | 423 | /* Add checksum to the starting values */ |
428 | ctx->hash[0] = A_save + A; | 424 | ctx->hash[0] += A; |
429 | ctx->hash[1] = B_save + B; | 425 | ctx->hash[1] += B; |
430 | ctx->hash[2] = C_save + C; | 426 | ctx->hash[2] += C; |
431 | ctx->hash[3] = D_save + D; | 427 | ctx->hash[3] += D; |
432 | #endif | 428 | #endif |
433 | } | 429 | } |
434 | #undef FF | 430 | #undef FF |
diff --git a/libbb/human_readable.c b/libbb/human_readable.c index 0b2eb777e..5c7fc076f 100644 --- a/libbb/human_readable.c +++ b/libbb/human_readable.c | |||
@@ -37,8 +37,6 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, | |||
37 | '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' | 37 | '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static char *str; | ||
41 | |||
42 | unsigned frac; /* 0..9 - the fractional digit */ | 40 | unsigned frac; /* 0..9 - the fractional digit */ |
43 | const char *u; | 41 | const char *u; |
44 | const char *fmt; | 42 | const char *fmt; |
@@ -81,12 +79,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, | |||
81 | #endif | 79 | #endif |
82 | } | 80 | } |
83 | 81 | ||
84 | if (!str) { | 82 | return auto_string(xasprintf(fmt, val, frac, *u)); |
85 | /* sufficient for any width of val */ | ||
86 | str = xmalloc(sizeof(val)*3 + 2 + 3); | ||
87 | } | ||
88 | sprintf(str, fmt, val, frac, *u); | ||
89 | return str; | ||
90 | } | 83 | } |
91 | 84 | ||
92 | 85 | ||
diff --git a/libbb/messages.c b/libbb/messages.c index ef42b30d7..108cb0285 100644 --- a/libbb/messages.c +++ b/libbb/messages.c | |||
@@ -45,7 +45,7 @@ const char bb_PATH_root_path[] ALIGN1 = | |||
45 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; | 45 | "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; |
46 | 46 | ||
47 | 47 | ||
48 | const int const_int_1 = 1; | 48 | //const int const_int_1 = 1; |
49 | /* explicitly = 0, otherwise gcc may make it a common variable | 49 | /* explicitly = 0, otherwise gcc may make it a common variable |
50 | * and it will end up in bss */ | 50 | * and it will end up in bss */ |
51 | const int const_int_0 = 0; | 51 | const int const_int_0 = 0; |
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c index 5a4e1c579..bddd39bca 100644 --- a/libbb/parse_mode.c +++ b/libbb/parse_mode.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) | 16 | #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) |
17 | 17 | ||
18 | int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | 18 | int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) |
19 | { | 19 | { |
20 | static const mode_t who_mask[] = { | 20 | static const mode_t who_mask[] = { |
21 | S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ | 21 | 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) | |||
46 | 46 | ||
47 | tmp = strtoul(s, &e, 8); | 47 | tmp = strtoul(s, &e, 8); |
48 | if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ | 48 | if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ |
49 | return 0; | 49 | return -1; |
50 | } | 50 | } |
51 | *current_mode = tmp; | 51 | return tmp; |
52 | return 1; | ||
53 | } | 52 | } |
54 | 53 | ||
55 | new_mode = *current_mode; | 54 | new_mode = current_mode; |
56 | 55 | ||
57 | /* Note: we allow empty clauses, and hence empty modes. | 56 | /* Note: we allow empty clauses, and hence empty modes. |
58 | * We treat an empty mode as no change to perms. */ | 57 | * 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) | |||
71 | if (*p == *s) { | 70 | if (*p == *s) { |
72 | wholist |= who_mask[(int)(p-who_chars)]; | 71 | wholist |= who_mask[(int)(p-who_chars)]; |
73 | if (!*++s) { | 72 | if (!*++s) { |
74 | return 0; | 73 | return -1; |
75 | } | 74 | } |
76 | goto WHO_LIST; | 75 | goto WHO_LIST; |
77 | } | 76 | } |
@@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) | |||
80 | do { /* Process action list. */ | 79 | do { /* Process action list. */ |
81 | if ((*s != '+') && (*s != '-')) { | 80 | if ((*s != '+') && (*s != '-')) { |
82 | if (*s != '=') { | 81 | if (*s != '=') { |
83 | return 0; | 82 | return -1; |
84 | } | 83 | } |
85 | /* Since op is '=', clear all bits corresponding to the | 84 | /* Since op is '=', clear all bits corresponding to the |
86 | * wholist, or all file bits if wholist is empty. */ | 85 | * 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) | |||
145 | } while (*s && (*s != ',')); | 144 | } while (*s && (*s != ',')); |
146 | } | 145 | } |
147 | 146 | ||
148 | *current_mode = new_mode; | 147 | return new_mode; |
149 | return 1; | ||
150 | } | 148 | } |
diff --git a/libbb/printable_string.c b/libbb/printable_string.c index 3e768d0b9..e638a178e 100644 --- a/libbb/printable_string.c +++ b/libbb/printable_string.c | |||
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) | 12 | const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) |
13 | { | 13 | { |
14 | static char *saved[4]; | ||
15 | static unsigned cur_saved; /* = 0 */ | ||
16 | |||
17 | char *dst; | 14 | char *dst; |
18 | const char *s; | 15 | const char *s; |
19 | 16 | ||
@@ -56,10 +53,5 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) | |||
56 | } | 53 | } |
57 | } | 54 | } |
58 | #endif | 55 | #endif |
59 | 56 | return auto_string(dst); | |
60 | free(saved[cur_saved]); | ||
61 | saved[cur_saved] = dst; | ||
62 | cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); | ||
63 | |||
64 | return dst; | ||
65 | } | 57 | } |
diff --git a/libbb/procps.c b/libbb/procps.c index 32dae43e3..5a4ea59d0 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -284,7 +284,6 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
284 | } | 284 | } |
285 | #endif | 285 | #endif |
286 | 286 | ||
287 | void BUG_comm_size(void); | ||
288 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | 287 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) |
289 | { | 288 | { |
290 | if (!sp) | 289 | if (!sp) |
@@ -386,8 +385,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
386 | /*if (!cp || cp[1] != ' ') | 385 | /*if (!cp || cp[1] != ' ') |
387 | continue;*/ | 386 | continue;*/ |
388 | cp[0] = '\0'; | 387 | cp[0] = '\0'; |
389 | if (sizeof(sp->comm) < 16) | 388 | BUILD_BUG_ON(sizeof(sp->comm) < 16); |
390 | BUG_comm_size(); | ||
391 | comm1 = strchr(buf, '('); | 389 | comm1 = strchr(buf, '('); |
392 | /*if (comm1)*/ | 390 | /*if (comm1)*/ |
393 | safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); | 391 | safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); |
diff --git a/libbb/udp_io.c b/libbb/udp_io.c index 7985a9723..a32af9bd2 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c | |||
@@ -16,10 +16,10 @@ void FAST_FUNC | |||
16 | socket_want_pktinfo(int fd UNUSED_PARAM) | 16 | socket_want_pktinfo(int fd UNUSED_PARAM) |
17 | { | 17 | { |
18 | #ifdef IP_PKTINFO | 18 | #ifdef IP_PKTINFO |
19 | setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); | 19 | setsockopt_1(fd, IPPROTO_IP, IP_PKTINFO); |
20 | #endif | 20 | #endif |
21 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) | 21 | #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) |
22 | setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); | 22 | setsockopt_1(fd, IPPROTO_IPV6, IPV6_PKTINFO); |
23 | #endif | 23 | #endif |
24 | } | 24 | } |
25 | 25 | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index de4d14fce..2d3204507 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -71,28 +71,44 @@ pid_t FAST_FUNC xspawn(char **argv) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | #if ENABLE_FEATURE_PREFER_APPLETS | 73 | #if ENABLE_FEATURE_PREFER_APPLETS |
74 | static jmp_buf die_jmp; | ||
75 | static void jump(void) | ||
76 | { | ||
77 | /* Special case. We arrive here if NOFORK applet | ||
78 | * calls xfunc, which then decides to die. | ||
79 | * We don't die, but jump instead back to caller. | ||
80 | * NOFORK applets still cannot carelessly call xfuncs: | ||
81 | * p = xmalloc(10); | ||
82 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
83 | */ | ||
84 | /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). | ||
85 | * This works because exitcodes are bytes, | ||
86 | * run_nofork_applet() ensures that by "& 0xff" */ | ||
87 | longjmp(die_jmp, xfunc_error_retval | 0x100); | ||
88 | } | ||
89 | |||
74 | struct nofork_save_area { | 90 | struct nofork_save_area { |
75 | jmp_buf die_jmp; | 91 | jmp_buf die_jmp; |
92 | void (*die_func)(void); | ||
76 | const char *applet_name; | 93 | const char *applet_name; |
77 | uint32_t option_mask32; | 94 | uint32_t option_mask32; |
78 | int die_sleep; | ||
79 | uint8_t xfunc_error_retval; | 95 | uint8_t xfunc_error_retval; |
80 | }; | 96 | }; |
81 | static void save_nofork_data(struct nofork_save_area *save) | 97 | static void save_nofork_data(struct nofork_save_area *save) |
82 | { | 98 | { |
83 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); | 99 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); |
100 | save->die_func = die_func; | ||
84 | save->applet_name = applet_name; | 101 | save->applet_name = applet_name; |
85 | save->xfunc_error_retval = xfunc_error_retval; | ||
86 | save->option_mask32 = option_mask32; | 102 | save->option_mask32 = option_mask32; |
87 | save->die_sleep = die_sleep; | 103 | save->xfunc_error_retval = xfunc_error_retval; |
88 | } | 104 | } |
89 | static void restore_nofork_data(struct nofork_save_area *save) | 105 | static void restore_nofork_data(struct nofork_save_area *save) |
90 | { | 106 | { |
91 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); | 107 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); |
108 | die_func = save->die_func; | ||
92 | applet_name = save->applet_name; | 109 | applet_name = save->applet_name; |
93 | xfunc_error_retval = save->xfunc_error_retval; | ||
94 | option_mask32 = save->option_mask32; | 110 | option_mask32 = save->option_mask32; |
95 | die_sleep = save->die_sleep; | 111 | xfunc_error_retval = save->xfunc_error_retval; |
96 | } | 112 | } |
97 | 113 | ||
98 | int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | 114 | int FAST_FUNC run_nofork_applet(int applet_no, char **argv) |
@@ -135,11 +151,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
135 | while (argv[argc]) | 151 | while (argv[argc]) |
136 | argc++; | 152 | argc++; |
137 | 153 | ||
138 | /* Special flag for xfunc_die(). If xfunc will "die" | 154 | /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ |
139 | * in NOFORK applet, xfunc_die() sees negative | 155 | die_func = jump; |
140 | * die_sleep and longjmp here instead. */ | ||
141 | die_sleep = -1; | ||
142 | |||
143 | rc = setjmp(die_jmp); | 156 | rc = setjmp(die_jmp); |
144 | if (!rc) { | 157 | if (!rc) { |
145 | /* Some callers (xargs) | 158 | /* Some callers (xargs) |
@@ -148,10 +161,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
148 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 161 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
149 | /* Finally we can call NOFORK applet's main() */ | 162 | /* Finally we can call NOFORK applet's main() */ |
150 | rc = applet_main[applet_no](argc, tmp_argv); | 163 | rc = applet_main[applet_no](argc, tmp_argv); |
151 | } else { /* xfunc died in NOFORK applet */ | 164 | } else { |
152 | /* in case they meant to return 0... */ | 165 | /* xfunc died in NOFORK applet */ |
153 | if (rc == -2222) | ||
154 | rc = 0; | ||
155 | } | 166 | } |
156 | 167 | ||
157 | /* Restoring some globals */ | 168 | /* Restoring some globals */ |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 442482a8b..0a4d8f128 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -14,13 +14,34 @@ | |||
14 | #include <sys/un.h> | 14 | #include <sys/un.h> |
15 | #include "libbb.h" | 15 | #include "libbb.h" |
16 | 16 | ||
17 | int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval) | ||
18 | { | ||
19 | return setsockopt(fd, level, optname, &optval, sizeof(int)); | ||
20 | } | ||
21 | int FAST_FUNC setsockopt_1(int fd, int level, int optname) | ||
22 | { | ||
23 | return setsockopt_int(fd, level, optname, 1); | ||
24 | } | ||
25 | int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) | ||
26 | { | ||
27 | return setsockopt_int(fd, SOL_SOCKET, optname, optval); | ||
28 | } | ||
29 | int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname) | ||
30 | { | ||
31 | return setsockopt_SOL_SOCKET_int(fd, optname, 1); | ||
32 | } | ||
33 | |||
17 | void FAST_FUNC setsockopt_reuseaddr(int fd) | 34 | void FAST_FUNC setsockopt_reuseaddr(int fd) |
18 | { | 35 | { |
19 | setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1)); | 36 | setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR); |
20 | } | 37 | } |
21 | int FAST_FUNC setsockopt_broadcast(int fd) | 38 | int FAST_FUNC setsockopt_broadcast(int fd) |
22 | { | 39 | { |
23 | return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); | 40 | return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST); |
41 | } | ||
42 | int FAST_FUNC setsockopt_keepalive(int fd) | ||
43 | { | ||
44 | return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE); | ||
24 | } | 45 | } |
25 | 46 | ||
26 | #ifdef SO_BINDTODEVICE | 47 | #ifdef SO_BINDTODEVICE |
diff --git a/libbb/xfunc_die.c b/libbb/xfunc_die.c index 204e5e49d..73f7998e5 100644 --- a/libbb/xfunc_die.c +++ b/libbb/xfunc_die.c | |||
@@ -7,34 +7,16 @@ | |||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* Keeping it separate allows to NOT suck in stdio for VERY small applets. | 10 | /* Keeping it separate allows to NOT pull in stdio for VERY small applets. |
11 | * Try building busybox with only "true" enabled... */ | 11 | * Try building busybox with only "true" enabled... */ |
12 | 12 | ||
13 | #include "libbb.h" | 13 | #include "libbb.h" |
14 | 14 | ||
15 | int die_sleep; | 15 | void (*die_func)(void); |
16 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH | ||
17 | jmp_buf die_jmp; | ||
18 | #endif | ||
19 | 16 | ||
20 | void FAST_FUNC xfunc_die(void) | 17 | void FAST_FUNC xfunc_die(void) |
21 | { | 18 | { |
22 | if (die_sleep) { | 19 | if (die_func) |
23 | if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) | 20 | die_func(); |
24 | && die_sleep < 0 | ||
25 | ) { | ||
26 | /* Special case. We arrive here if NOFORK applet | ||
27 | * calls xfunc, which then decides to die. | ||
28 | * We don't die, but jump instead back to caller. | ||
29 | * NOFORK applets still cannot carelessly call xfuncs: | ||
30 | * p = xmalloc(10); | ||
31 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
32 | */ | ||
33 | /* -2222 means "zero" (longjmp can't pass 0) | ||
34 | * run_nofork_applet() catches -2222. */ | ||
35 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); | ||
36 | } | ||
37 | sleep(die_sleep); | ||
38 | } | ||
39 | exit(xfunc_error_retval); | 21 | exit(xfunc_error_retval); |
40 | } | 22 | } |