aboutsummaryrefslogtreecommitdiff
path: root/libbb/read_printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/read_printf.c')
-rw-r--r--libbb/read_printf.c17
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 */
58ssize_t FAST_FUNC nonblock_safe_read(int fd, void *buf, size_t count) 58ssize_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).
77char* FAST_FUNC xmalloc_reads(int fd, char *buf, size_t *maxsz_p) 78char* 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;