diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-09-27 10:09:59 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-09-27 10:09:59 +0000 |
commit | 5d61e71c3a8ac3296afbfe9a014c62050c5a9234 (patch) | |
tree | e9ab2cd35d1f2d51b26a678551a0439b1719928b | |
parent | c9dc2ac578278e86be248cc21e53081f7054da83 (diff) | |
download | busybox-w32-5d61e71c3a8ac3296afbfe9a014c62050c5a9234.tar.gz busybox-w32-5d61e71c3a8ac3296afbfe9a014c62050c5a9234.tar.bz2 busybox-w32-5d61e71c3a8ac3296afbfe9a014c62050c5a9234.zip |
introduce safe_poll (fixes a problem in top)
function old new delta
safe_poll - 77 +77
svlogd_main 1470 1466 -4
zcip_main 1530 1524 -6
forkexec 1345 1338 -7
decode_format_string 795 788 -7
collect_blk 474 467 -7
buffer_pread 540 532 -8
tftp 1182 1172 -10
microcom_main 763 749 -14
arpping 441 424 -17
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/9 up/down: 77/-80) Total: -3 bytes
text data bss dec hex filename
770162 1034 10404 781600 bed20 busybox_old
770158 1034 10404 781596 bed1c busybox_unstripped
-rw-r--r-- | editors/vi.c | 4 | ||||
-rw-r--r-- | include/libbb.h | 8 | ||||
-rw-r--r-- | libbb/Kbuild | 1 | ||||
-rw-r--r-- | libbb/safe_poll.c | 34 | ||||
-rw-r--r-- | libbb/safe_strncpy.c | 2 | ||||
-rw-r--r-- | miscutils/microcom.c | 3 | ||||
-rw-r--r-- | networking/httpd.c | 6 | ||||
-rw-r--r-- | networking/tftp.c | 4 | ||||
-rw-r--r-- | networking/traceroute.c | 2 | ||||
-rw-r--r-- | networking/udhcp/arpping.c | 7 | ||||
-rw-r--r-- | networking/zcip.c | 14 | ||||
-rw-r--r-- | procps/top.c | 2 | ||||
-rw-r--r-- | runit/svlogd.c | 8 |
13 files changed, 65 insertions, 30 deletions
diff --git a/editors/vi.c b/editors/vi.c index f5df41636..1fa7c3a09 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2139,7 +2139,7 @@ static int mysleep(int hund) // sleep for 'h' 1/100 seconds | |||
2139 | 2139 | ||
2140 | pfd[0].fd = 0; | 2140 | pfd[0].fd = 0; |
2141 | pfd[0].events = POLLIN; | 2141 | pfd[0].events = POLLIN; |
2142 | return poll(pfd, 1, hund*10) > 0; | 2142 | return safe_poll(pfd, 1, hund*10) > 0; |
2143 | } | 2143 | } |
2144 | 2144 | ||
2145 | #define readbuffer bb_common_bufsiz1 | 2145 | #define readbuffer bb_common_bufsiz1 |
@@ -2221,7 +2221,7 @@ static char readit(void) // read (maybe cursor) key from stdin | |||
2221 | pfd[0].events = POLLIN; | 2221 | pfd[0].events = POLLIN; |
2222 | // Wait 50 ms | 2222 | // Wait 50 ms |
2223 | // keep reading while there are input chars and room in buffer | 2223 | // keep reading while there are input chars and room in buffer |
2224 | while (poll(pfd, 1, 50) > 0 && n <= (MAX_LINELEN - 5)) { | 2224 | while (safe_poll(pfd, 1, 50) > 0 && n <= (MAX_LINELEN - 5)) { |
2225 | // read the rest of the ESC string | 2225 | // read the rest of the ESC string |
2226 | int r = read(0, readbuffer + n, MAX_LINELEN - n); | 2226 | int r = read(0, readbuffer + n, MAX_LINELEN - n); |
2227 | if (r > 0) | 2227 | if (r > 0) |
diff --git a/include/libbb.h b/include/libbb.h index 407b723b2..26a0f0d4a 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -451,8 +451,14 @@ extern FILE *fopen_or_warn(const char *filename, const char *mode); | |||
451 | /* "Opens" stdin if filename is special, else just opens file: */ | 451 | /* "Opens" stdin if filename is special, else just opens file: */ |
452 | extern FILE *fopen_or_warn_stdin(const char *filename); | 452 | extern FILE *fopen_or_warn_stdin(const char *filename); |
453 | 453 | ||
454 | /* Wrapper which restarts poll on EINTR or ENOMEM. | ||
455 | * On other errors complains [perror("poll")] and returns. | ||
456 | * Warning! May take (much) longer than timeout_ms to return! | ||
457 | * If this is a problem, use bare poll and open-code EINTR/ENOMEM handling */ | ||
458 | int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms); | ||
459 | |||
454 | /* Convert each alpha char in str to lower-case */ | 460 | /* Convert each alpha char in str to lower-case */ |
455 | extern char* str_tolower(char *str); | 461 | char* str_tolower(char *str); |
456 | 462 | ||
457 | char *utoa(unsigned n); | 463 | char *utoa(unsigned n); |
458 | char *itoa(int n); | 464 | char *itoa(int n); |
diff --git a/libbb/Kbuild b/libbb/Kbuild index 1800bde8f..55b3658b4 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -71,6 +71,7 @@ lib-y += recursive_action.o | |||
71 | lib-y += remove_file.o | 71 | lib-y += remove_file.o |
72 | lib-y += restricted_shell.o | 72 | lib-y += restricted_shell.o |
73 | lib-y += run_shell.o | 73 | lib-y += run_shell.o |
74 | lib-y += safe_poll.o | ||
74 | lib-y += safe_strncpy.o | 75 | lib-y += safe_strncpy.o |
75 | lib-y += safe_write.o | 76 | lib-y += safe_write.o |
76 | lib-y += setup_environment.o | 77 | lib-y += setup_environment.o |
diff --git a/libbb/safe_poll.c b/libbb/safe_poll.c new file mode 100644 index 000000000..d2b773c36 --- /dev/null +++ b/libbb/safe_poll.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2007 by Denys Vlasenko <vda.linux@googlemail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this tarball for details. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | |||
12 | /* Wrapper which restarts poll on EINTR or ENOMEM. | ||
13 | * On other errors does perror("poll") and returns. | ||
14 | * Warning! May take longer than timeout_ms to return! */ | ||
15 | int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout) | ||
16 | { | ||
17 | while (1) { | ||
18 | int n = poll(ufds, nfds, timeout); | ||
19 | if (n >= 0) | ||
20 | return n; | ||
21 | /* Make sure we inch towards completion */ | ||
22 | if (timeout > 0) | ||
23 | timeout--; | ||
24 | /* E.g. strace causes poll to return this */ | ||
25 | if (errno == EINTR) | ||
26 | continue; | ||
27 | /* Kernel is very low on memory. Retry. */ | ||
28 | /* I doubt many callers would handle this correctly! */ | ||
29 | if (errno == ENOMEM) | ||
30 | continue; | ||
31 | bb_perror_msg("poll"); | ||
32 | return n; | ||
33 | } | ||
34 | } | ||
diff --git a/libbb/safe_strncpy.c b/libbb/safe_strncpy.c index ebc7e28f3..cc425839f 100644 --- a/libbb/safe_strncpy.c +++ b/libbb/safe_strncpy.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | /* Like strncpy but make sure the resulting string is always 0 terminated. */ | 12 | /* Like strncpy but make sure the resulting string is always 0 terminated. */ |
13 | char * safe_strncpy(char *dst, const char *src, size_t size) | 13 | char *safe_strncpy(char *dst, const char *src, size_t size) |
14 | { | 14 | { |
15 | if (!size) return dst; | 15 | if (!size) return dst; |
16 | dst[--size] = '\0'; | 16 | dst[--size] = '\0'; |
diff --git a/miscutils/microcom.c b/miscutils/microcom.c index 59a91024e..5928569d5 100644 --- a/miscutils/microcom.c +++ b/miscutils/microcom.c | |||
@@ -105,8 +105,7 @@ int microcom_main(int argc, char **argv) | |||
105 | pfd[1].events = POLLIN; | 105 | pfd[1].events = POLLIN; |
106 | while (1) { | 106 | while (1) { |
107 | int i; | 107 | int i; |
108 | while (-1 == poll(pfd, 2, -1) && EINTR == errno) | 108 | safe_poll(pfd, 2, -1); |
109 | continue; | ||
110 | for (i = 0; i < 2; ++i) { | 109 | for (i = 0; i < 2; ++i) { |
111 | if (pfd[i].revents & POLLIN) { | 110 | if (pfd[i].revents & POLLIN) { |
112 | len = read(pfd[i].fd, bb_common_bufsiz1, COMMON_BUFSIZE); | 111 | len = read(pfd[i].fd, bb_common_bufsiz1, COMMON_BUFSIZE); |
diff --git a/networking/httpd.c b/networking/httpd.c index cedec800f..92a07107d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -1073,13 +1073,9 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | /* Now wait on the set of sockets */ | 1075 | /* Now wait on the set of sockets */ |
1076 | count = poll(pfd, 3, -1); | 1076 | count = safe_poll(pfd, 3, -1); |
1077 | if (count <= 0) { | 1077 | if (count <= 0) { |
1078 | #if 0 | 1078 | #if 0 |
1079 | if (errno == EINTR) | ||
1080 | continue; | ||
1081 | #endif | ||
1082 | #if 0 | ||
1083 | if (waitpid(pid, &status, WNOHANG) <= 0) { | 1079 | if (waitpid(pid, &status, WNOHANG) <= 0) { |
1084 | /* Weird. CGI didn't exit and no fd's | 1080 | /* Weird. CGI didn't exit and no fd's |
1085 | * are ready, yet poll returned?! */ | 1081 | * are ready, yet poll returned?! */ |
diff --git a/networking/tftp.c b/networking/tftp.c index ac3a86afb..59f53ae4a 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -225,7 +225,7 @@ static int tftp( USE_GETPUT(const int cmd,) | |||
225 | /* Receive packet */ | 225 | /* Receive packet */ |
226 | /*pfd[0].fd = socketfd;*/ | 226 | /*pfd[0].fd = socketfd;*/ |
227 | pfd[0].events = POLLIN; | 227 | pfd[0].events = POLLIN; |
228 | switch (poll(pfd, 1, waittime_ms)) { | 228 | switch (safe_poll(pfd, 1, waittime_ms)) { |
229 | unsigned from_port; | 229 | unsigned from_port; |
230 | case 1: | 230 | case 1: |
231 | from->len = peer_lsa->len; | 231 | from->len = peer_lsa->len; |
@@ -262,7 +262,7 @@ static int tftp( USE_GETPUT(const int cmd,) | |||
262 | 262 | ||
263 | goto send_again; /* resend last sent pkt */ | 263 | goto send_again; /* resend last sent pkt */ |
264 | default: | 264 | default: |
265 | bb_perror_msg("poll"); | 265 | /*bb_perror_msg("poll"); - done in safe_poll */ |
266 | goto ret; | 266 | goto ret; |
267 | } | 267 | } |
268 | process_pkt: | 268 | process_pkt: |
diff --git a/networking/traceroute.c b/networking/traceroute.c index 21921e56d..2d09c7197 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -543,7 +543,7 @@ wait_for_reply(int sock, struct sockaddr_in *fromp) | |||
543 | 543 | ||
544 | pfd[0].fd = sock; | 544 | pfd[0].fd = sock; |
545 | pfd[0].events = POLLIN; | 545 | pfd[0].events = POLLIN; |
546 | if (poll(pfd, 1, waittime * 1000) > 0) | 546 | if (safe_poll(pfd, 1, waittime * 1000) > 0) |
547 | cc = recvfrom(sock, packet, sizeof(packet), 0, | 547 | cc = recvfrom(sock, packet, sizeof(packet), 0, |
548 | (struct sockaddr *)fromp, &fromlen); | 548 | (struct sockaddr *)fromp, &fromlen); |
549 | return cc; | 549 | return cc; |
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c index 33518077b..7b702d8f3 100644 --- a/networking/udhcp/arpping.c +++ b/networking/udhcp/arpping.c | |||
@@ -81,12 +81,9 @@ int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *i | |||
81 | unsigned prevTime = monotonic_us(); | 81 | unsigned prevTime = monotonic_us(); |
82 | 82 | ||
83 | pfd[0].events = POLLIN; | 83 | pfd[0].events = POLLIN; |
84 | r = poll(pfd, 1, timeout_ms); | 84 | r = safe_poll(pfd, 1, timeout_ms); |
85 | if (r < 0) { | 85 | if (r < 0) { |
86 | if (errno != EINTR) { | 86 | break; |
87 | bb_perror_msg("poll"); | ||
88 | break; | ||
89 | } | ||
90 | } else if (r) { | 87 | } else if (r) { |
91 | if (read(s, &arp, sizeof(arp)) < 0) | 88 | if (read(s, &arp, sizeof(arp)) < 0) |
92 | break; | 89 | break; |
diff --git a/networking/zcip.c b/networking/zcip.c index 2f0b5a7fb..63846ebef 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -300,7 +300,12 @@ int zcip_main(int argc, char **argv) | |||
300 | 300 | ||
301 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", | 301 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", |
302 | timeout_ms, intf, nprobes, nclaims); | 302 | timeout_ms, intf, nprobes, nclaims); |
303 | switch (poll(fds, 1, timeout_ms)) { | 303 | |
304 | switch (safe_poll(fds, 1, timeout_ms)) { | ||
305 | |||
306 | default: | ||
307 | /*bb_perror_msg("poll"); - done in safe_poll */ | ||
308 | return EXIT_FAILURE; | ||
304 | 309 | ||
305 | // timeout | 310 | // timeout |
306 | case 0: | 311 | case 0: |
@@ -388,6 +393,7 @@ int zcip_main(int argc, char **argv) | |||
388 | break; | 393 | break; |
389 | } // switch (state) | 394 | } // switch (state) |
390 | break; // case 0 (timeout) | 395 | break; // case 0 (timeout) |
396 | |||
391 | // packets arriving | 397 | // packets arriving |
392 | case 1: | 398 | case 1: |
393 | // We need to adjust the timeout in case we didn't receive | 399 | // We need to adjust the timeout in case we didn't receive |
@@ -519,13 +525,9 @@ int zcip_main(int argc, char **argv) | |||
519 | nclaims = 0; | 525 | nclaims = 0; |
520 | break; | 526 | break; |
521 | } // switch state | 527 | } // switch state |
522 | |||
523 | break; // case 1 (packets arriving) | 528 | break; // case 1 (packets arriving) |
524 | default: | ||
525 | why = "poll"; | ||
526 | goto bad; | ||
527 | } // switch poll | 529 | } // switch poll |
528 | } | 530 | } // while (1) |
529 | bad: | 531 | bad: |
530 | bb_perror_msg("%s, %s", intf, why); | 532 | bb_perror_msg("%s, %s", intf, why); |
531 | return EXIT_FAILURE; | 533 | return EXIT_FAILURE; |
diff --git a/procps/top.c b/procps/top.c index ac3b7e5a2..e55cecccb 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -924,7 +924,7 @@ int top_main(int argc, char **argv) | |||
924 | #if !ENABLE_FEATURE_USE_TERMIOS | 924 | #if !ENABLE_FEATURE_USE_TERMIOS |
925 | sleep(interval); | 925 | sleep(interval); |
926 | #else | 926 | #else |
927 | if (poll(pfd, 1, interval * 1000) != 0) { | 927 | if (safe_poll(pfd, 1, interval * 1000) > 0) { |
928 | if (read(0, &c, 1) != 1) /* signal */ | 928 | if (read(0, &c, 1) != 1) /* signal */ |
929 | break; | 929 | break; |
930 | if (c == initial_settings.c_cc[VINTR]) | 930 | if (c == initial_settings.c_cc[VINTR]) |
diff --git a/runit/svlogd.c b/runit/svlogd.c index 6c8747e96..b5eed15ab 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c | |||
@@ -665,7 +665,7 @@ static ssize_t ndelay_read(int fd, void *buf, size_t count) | |||
665 | } | 665 | } |
666 | 666 | ||
667 | /* Used for reading stdin */ | 667 | /* Used for reading stdin */ |
668 | static int buffer_pread(int fd, char *s, unsigned len) | 668 | static int buffer_pread(/*int fd, */char *s, unsigned len) |
669 | { | 669 | { |
670 | unsigned now; | 670 | unsigned now; |
671 | struct pollfd input; | 671 | struct pollfd input; |
@@ -709,7 +709,7 @@ static int buffer_pread(int fd, char *s, unsigned len) | |||
709 | poll(&input, 1, i * 1000); | 709 | poll(&input, 1, i * 1000); |
710 | sigprocmask(SIG_BLOCK, blocked_sigset, NULL); | 710 | sigprocmask(SIG_BLOCK, blocked_sigset, NULL); |
711 | 711 | ||
712 | i = ndelay_read(fd, s, len); | 712 | i = ndelay_read(0, s, len); |
713 | if (i >= 0) | 713 | if (i >= 0) |
714 | break; | 714 | break; |
715 | if (errno == EINTR) | 715 | if (errno == EINTR) |
@@ -909,7 +909,7 @@ int svlogd_main(int argc, char **argv) | |||
909 | if (!np && !exitasap) { | 909 | if (!np && !exitasap) { |
910 | i = linemax - stdin_cnt; /* avail. bytes at tail */ | 910 | i = linemax - stdin_cnt; /* avail. bytes at tail */ |
911 | if (i >= 128) { | 911 | if (i >= 128) { |
912 | i = buffer_pread(0, lineptr + stdin_cnt, i); | 912 | i = buffer_pread(/*0, */lineptr + stdin_cnt, i); |
913 | if (i <= 0) /* EOF or error on stdin */ | 913 | if (i <= 0) /* EOF or error on stdin */ |
914 | exitasap = 1; | 914 | exitasap = 1; |
915 | else { | 915 | else { |
@@ -966,7 +966,7 @@ int svlogd_main(int argc, char **argv) | |||
966 | /* read/write repeatedly until we see it */ | 966 | /* read/write repeatedly until we see it */ |
967 | while (ch != '\n') { | 967 | while (ch != '\n') { |
968 | /* lineptr is emptied now, safe to use as buffer */ | 968 | /* lineptr is emptied now, safe to use as buffer */ |
969 | stdin_cnt = exitasap ? -1 : buffer_pread(0, lineptr, linemax); | 969 | stdin_cnt = exitasap ? -1 : buffer_pread(/*0, */lineptr, linemax); |
970 | if (stdin_cnt <= 0) { /* EOF or error on stdin */ | 970 | if (stdin_cnt <= 0) { /* EOF or error on stdin */ |
971 | exitasap = 1; | 971 | exitasap = 1; |
972 | lineptr[0] = ch = '\n'; | 972 | lineptr[0] = ch = '\n'; |