diff options
Diffstat (limited to 'libbb/read_printf.c')
-rw-r--r-- | libbb/read_printf.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 8664bc625..192f83d6e 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c | |||
@@ -55,32 +55,35 @@ | |||
55 | * which detects EAGAIN and uses poll() to wait on the fd. | 55 | * which detects EAGAIN and uses poll() to wait on the fd. |
56 | * Thankfully, poll() doesn't care about O_NONBLOCK flag. | 56 | * Thankfully, poll() doesn't care about O_NONBLOCK flag. |
57 | */ | 57 | */ |
58 | ssize_t FAST_FUNC nonblock_safe_read(int fd, void *buf, size_t count) | 58 | ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) |
59 | { | 59 | { |
60 | struct pollfd pfd[1]; | 60 | struct pollfd pfd[1]; |
61 | ssize_t n; | 61 | ssize_t n; |
62 | 62 | ||
63 | while (1) { | 63 | while (1) { |
64 | n = safe_read(fd, buf, count); | 64 | n = loop_on_EINTR ? safe_read(fd, buf, count) : read(fd, buf, count); |
65 | if (n >= 0 || errno != EAGAIN) | 65 | if (n >= 0 || errno != EAGAIN) |
66 | return n; | 66 | return n; |
67 | /* fd is in O_NONBLOCK mode. Wait using poll and repeat */ | 67 | /* fd is in O_NONBLOCK mode. Wait using poll and repeat */ |
68 | pfd[0].fd = fd; | 68 | pfd[0].fd = fd; |
69 | pfd[0].events = POLLIN; | 69 | pfd[0].events = POLLIN; |
70 | safe_poll(pfd, 1, -1); /* note: this pulls in printf */ | 70 | /* note: safe_poll pulls in printf */ |
71 | loop_on_EINTR ? safe_poll(pfd, 1, -1) : poll(pfd, 1, -1); | ||
71 | } | 72 | } |
72 | } | 73 | } |
73 | 74 | ||
74 | // Reads one line a-la fgets (but doesn't save terminating '\n'). | 75 | // Reads one line a-la fgets (but doesn't save terminating '\n'). |
75 | // Reads byte-by-byte. Useful when it is important to not read ahead. | 76 | // Reads byte-by-byte. Useful when it is important to not read ahead. |
76 | // Bytes are appended to pfx (which must be malloced, or NULL). | 77 | // Bytes are appended to pfx (which must be malloced, or NULL). |
77 | char* FAST_FUNC xmalloc_reads(int fd, char *buf, size_t *maxsz_p) | 78 | char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p) |
78 | { | 79 | { |
79 | char *p; | 80 | char *p; |
80 | size_t sz = buf ? strlen(buf) : 0; | 81 | char *buf = NULL; |
82 | size_t sz = 0; | ||
81 | size_t maxsz = maxsz_p ? *maxsz_p : (INT_MAX - 4095); | 83 | size_t maxsz = maxsz_p ? *maxsz_p : (INT_MAX - 4095); |
82 | 84 | ||
83 | goto jump_in; | 85 | goto jump_in; |
86 | |||
84 | while (sz < maxsz) { | 87 | while (sz < maxsz) { |
85 | if ((size_t)(p - buf) == sz) { | 88 | if ((size_t)(p - buf) == sz) { |
86 | jump_in: | 89 | jump_in: |
@@ -88,8 +91,8 @@ char* FAST_FUNC xmalloc_reads(int fd, char *buf, size_t *maxsz_p) | |||
88 | p = buf + sz; | 91 | p = buf + sz; |
89 | sz += 128; | 92 | sz += 128; |
90 | } | 93 | } |
91 | /* nonblock_safe_read() because we are used by e.g. shells */ | 94 | if (nonblock_immune_read(fd, p, 1, /*loop_on_EINTR:*/ 1) != 1) { |
92 | if (nonblock_safe_read(fd, p, 1) != 1) { /* EOF/error */ | 95 | /* EOF/error */ |
93 | if (p == buf) { /* we read nothing */ | 96 | if (p == buf) { /* we read nothing */ |
94 | free(buf); | 97 | free(buf); |
95 | return NULL; | 98 | return NULL; |