| 111 | */ |
| 112 | |
| 113 | static int |
| 114 | ptsdev_read(struct file *fp, struct uio *uio, struct ucred *active_cred, |
| 115 | int flags, struct thread *td) |
| 116 | { |
| 117 | struct tty *tp = fp->f_data; |
| 118 | struct pts_softc *psc = tty_softc(tp); |
| 119 | int error = 0; |
| 120 | char pkt; |
| 121 | |
| 122 | if (uio->uio_resid == 0) |
| 123 | return (0); |
| 124 | |
| 125 | tty_lock(tp); |
| 126 | |
| 127 | for (;;) { |
| 128 | /* |
| 129 | * Implement packet mode. When packet mode is turned on, |
| 130 | * the first byte contains a bitmask of events that |
| 131 | * occurred (start, stop, flush, window size, etc). |
| 132 | */ |
| 133 | if (psc->pts_flags & PTS_PKT && psc->pts_pkt) { |
| 134 | pkt = psc->pts_pkt; |
| 135 | psc->pts_pkt = 0; |
| 136 | tty_unlock(tp); |
| 137 | |
| 138 | error = ureadc(pkt, uio); |
| 139 | return (error); |
| 140 | } |
| 141 | |
| 142 | /* |
| 143 | * Transmit regular data. |
| 144 | * |
| 145 | * XXX: We shouldn't use ttydisc_getc_poll()! Even |
| 146 | * though in this implementation, there is likely going |
| 147 | * to be data, we should just call ttydisc_getc_uio() |
| 148 | * and use its return value to sleep. |
| 149 | */ |
| 150 | if (ttydisc_getc_poll(tp)) { |
| 151 | if (psc->pts_flags & PTS_PKT) { |
| 152 | /* |
| 153 | * XXX: Small race. Fortunately PTY |
| 154 | * consumers aren't multithreaded. |
| 155 | */ |
| 156 | |
| 157 | tty_unlock(tp); |
| 158 | error = ureadc(TIOCPKT_DATA, uio); |
| 159 | if (error) |
| 160 | return (error); |
| 161 | tty_lock(tp); |
| 162 | } |
| 163 | |
| 164 | error = ttydisc_getc_uio(tp, uio); |
| 165 | break; |
| 166 | } |
| 167 | |
| 168 | /* Maybe the device isn't used anyway. */ |
| 169 | if (psc->pts_flags & PTS_FINISHED) |
| 170 | break; |
nothing calls this directly
no test coverage detected