| 1215 | } |
| 1216 | |
| 1217 | int |
| 1218 | ttydisc_getc_uio(struct tty *tp, struct uio *uio) |
| 1219 | { |
| 1220 | int error = 0; |
| 1221 | ssize_t obytes = uio->uio_resid; |
| 1222 | size_t len; |
| 1223 | char buf[TTY_STACKBUF]; |
| 1224 | |
| 1225 | tty_assert_locked(tp); |
| 1226 | |
| 1227 | if (tp->t_flags & TF_STOPPED) |
| 1228 | return (0); |
| 1229 | |
| 1230 | /* |
| 1231 | * When a TTY hook is attached, we cannot perform unbuffered |
| 1232 | * copying to userspace. Just call ttydisc_getc() and |
| 1233 | * temporarily store data in a shadow buffer. |
| 1234 | */ |
| 1235 | if (ttyhook_hashook(tp, getc_capture) || |
| 1236 | ttyhook_hashook(tp, getc_inject)) { |
| 1237 | while (uio->uio_resid > 0) { |
| 1238 | /* Read to shadow buffer. */ |
| 1239 | len = ttydisc_getc(tp, buf, |
| 1240 | MIN(uio->uio_resid, sizeof buf)); |
| 1241 | if (len == 0) |
| 1242 | break; |
| 1243 | |
| 1244 | /* Copy to userspace. */ |
| 1245 | tty_unlock(tp); |
| 1246 | error = uiomove(buf, len, uio); |
| 1247 | tty_lock(tp); |
| 1248 | |
| 1249 | if (error != 0) |
| 1250 | break; |
| 1251 | } |
| 1252 | } else { |
| 1253 | error = ttyoutq_read_uio(&tp->t_outq, tp, uio); |
| 1254 | |
| 1255 | ttydisc_wakeup_watermark(tp); |
| 1256 | atomic_add_long(&tty_nout, obytes - uio->uio_resid); |
| 1257 | } |
| 1258 | |
| 1259 | return (error); |
| 1260 | } |
| 1261 | |
| 1262 | size_t |
| 1263 | ttydisc_getc_poll(struct tty *tp) |
no test coverage detected