- status = 0;
- startword = 2;
- backslash = 0;
-#if ENABLE_ASH_READ_TIMEOUT
- if (timeout) /* NB: ensuring end_ms is nonzero */
- end_ms = ((unsigned)(monotonic_us() / 1000) + timeout) | 1;
-#endif
- STARTSTACKSTR(p);
- do {
- const char *is_ifs;
-
-#if ENABLE_ASH_READ_TIMEOUT
- if (end_ms) {
- struct pollfd pfd[1];
- pfd[0].fd = fd;
- pfd[0].events = POLLIN;
- timeout = end_ms - (unsigned)(monotonic_us() / 1000);
- if ((int)timeout <= 0 /* already late? */
- || safe_poll(pfd, 1, timeout) != 1 /* no? wait... */
- ) { /* timed out! */
-#if ENABLE_ASH_READ_NCHARS
- tcsetattr(fd, TCSANOW, &old_tty);
-#endif
- return 1;
- }
- }
-#endif
- if (nonblock_safe_read(fd, &c, 1) != 1) {
- status = 1;
- break;
- }
- if (c == '\0')
- continue;
- if (backslash) {
- backslash = 0;
- if (c != '\n')
- goto put;
- continue;
- }
- if (!rflag && c == '\\') {
- backslash = 1;
- continue;
- }
- if (c == '\n')
- break;
- /* $IFS splitting */
-/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05 */
- is_ifs = strchr(ifs, c);
- if (startword && is_ifs) {
- if (isspace(c))
- continue;
- /* it is a non-space ifs char */
- startword--;
- if (startword == 1) /* first one? */
- continue; /* yes, it is not next word yet */
- }
- startword = 0;
- if (ap[1] != NULL && is_ifs) {
- const char *beg;
- STACKSTRNUL(p);
- beg = stackblock();
- setvar(*ap, beg, 0);
- ap++;
- /* can we skip one non-space ifs char? (2: yes) */
- startword = isspace(c) ? 2 : 1;
- STARTSTACKSTR(p);
- continue;
- }
- put:
- STPUTC(c, p);
- }
-/* end of do {} while: */
-#if ENABLE_ASH_READ_NCHARS
- while (--nchars);
-#else
- while (1);
-#endif