| 108 | } |
| 109 | |
| 110 | static int |
| 111 | ttydisc_read_canonical(struct tty *tp, struct uio *uio, int ioflag) |
| 112 | { |
| 113 | char breakc[4] = { CNL }; /* enough to hold \n, VEOF and VEOL. */ |
| 114 | int error; |
| 115 | size_t clen, flen = 0, n = 1; |
| 116 | unsigned char lastc = _POSIX_VDISABLE; |
| 117 | |
| 118 | #define BREAK_ADD(c) do { \ |
| 119 | if (tp->t_termios.c_cc[c] != _POSIX_VDISABLE) \ |
| 120 | breakc[n++] = tp->t_termios.c_cc[c]; \ |
| 121 | } while (0) |
| 122 | /* Determine which characters we should trigger on. */ |
| 123 | BREAK_ADD(VEOF); |
| 124 | BREAK_ADD(VEOL); |
| 125 | #undef BREAK_ADD |
| 126 | breakc[n] = '\0'; |
| 127 | |
| 128 | do { |
| 129 | error = tty_wait_background(tp, curthread, SIGTTIN); |
| 130 | if (error) |
| 131 | return (error); |
| 132 | |
| 133 | /* |
| 134 | * Quite a tricky case: unlike the old TTY |
| 135 | * implementation, this implementation copies data back |
| 136 | * to userspace in large chunks. Unfortunately, we can't |
| 137 | * calculate the line length on beforehand if it crosses |
| 138 | * ttyinq_block boundaries, because multiple reads could |
| 139 | * then make this code read beyond the newline. |
| 140 | * |
| 141 | * This is why we limit the read to: |
| 142 | * - The size the user has requested |
| 143 | * - The blocksize (done in tty_inq.c) |
| 144 | * - The amount of bytes until the newline |
| 145 | * |
| 146 | * This causes the line length to be recalculated after |
| 147 | * each block has been copied to userspace. This will |
| 148 | * cause the TTY layer to return data in chunks using |
| 149 | * the blocksize (except the first and last blocks). |
| 150 | */ |
| 151 | clen = ttyinq_findchar(&tp->t_inq, breakc, uio->uio_resid, |
| 152 | &lastc); |
| 153 | |
| 154 | /* No more data. */ |
| 155 | if (clen == 0) { |
| 156 | if (tp->t_flags & TF_ZOMBIE) |
| 157 | return (0); |
| 158 | else if (ioflag & IO_NDELAY) |
| 159 | return (EWOULDBLOCK); |
| 160 | |
| 161 | error = tty_wait(tp, &tp->t_inwait); |
| 162 | if (error) |
| 163 | return (error); |
| 164 | continue; |
| 165 | } |
| 166 | |
| 167 | /* Don't send the EOF char back to userspace. */ |
no test coverage detected