*/
#include "libbb.h"
#include "shell_common.h"
+#include <sys/resource.h> /* getrlimit */
const char defifsvar[] ALIGN1 = "IFS= \t\n";
/* read builtin */
-/* Needs to be interruptible: shell mush handle traps and shell-special signals
+/* Needs to be interruptible: shell must handle traps and shell-special signals
* while inside read. To implement this, be sure to not loop on EINTR
* and return errno == EINTR reliably.
*/
old_tty = tty;
if (nchars) {
tty.c_lflag &= ~ICANON;
- tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
+ // Setting it to more than 1 breaks poll():
+ // it blocks even if there's data. !??
+ //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255;
+ /* reads would block only if < 1 char is available */
+ tty.c_cc[VMIN] = 1;
+ /* no timeout (reads block forever) */
+ tty.c_cc[VTIME] = 0;
}
if (read_flags & BUILTIN_READ_SILENT) {
tty.c_lflag &= ~(ECHO | ECHOK | ECHONL);
bufpos = 0;
do {
char c;
+ struct pollfd pfd[1];
+ int timeout;
- errno = 0;
+ if ((bufpos & 0xff) == 0)
+ buffer = xrealloc(buffer, bufpos + 0x101);
+ timeout = -1;
if (end_ms) {
- int timeout;
- struct pollfd pfd[1];
-
- pfd[0].fd = fd;
- pfd[0].events = POLLIN;
timeout = end_ms - (unsigned)monotonic_ms();
- if (timeout <= 0 /* already late? */
- || poll(pfd, 1, timeout) != 1 /* no? wait... */
- ) { /* timed out! */
- err = errno;
+ if (timeout <= 0) { /* already late? */
retval = (const char *)(uintptr_t)1;
goto ret;
}
}
- if ((bufpos & 0xff) == 0)
- buffer = xrealloc(buffer, bufpos + 0x100);
- if (nonblock_immune_read(fd, &buffer[bufpos], 1, /*loop_on_EINTR:*/ 0) != 1) {
+ /* We must poll even if timeout is -1:
+ * we want to be interrupted if signal arrives,
+ * regardless of SA_RESTART-ness of that signal!
+ */
+ errno = 0;
+ pfd[0].fd = fd;
+ pfd[0].events = POLLIN;
+ if (poll(pfd, 1, timeout) != 1) {
+ /* timed out, or EINTR */
+ err = errno;
+ retval = (const char *)(uintptr_t)1;
+ goto ret;
+ }
+ if (read(fd, &buffer[bufpos], 1) != 1) {
err = errno;
retval = (const char *)(uintptr_t)1;
break;
}
+
c = buffer[bufpos];
if (c == '\0')
continue;