| 278 | } |
| 279 | |
| 280 | size_t |
| 281 | ttyinq_write(struct ttyinq *ti, const void *buf, size_t nbytes, int quote) |
| 282 | { |
| 283 | const char *cbuf = buf; |
| 284 | struct ttyinq_block *tib; |
| 285 | unsigned int boff; |
| 286 | size_t l; |
| 287 | |
| 288 | while (nbytes > 0) { |
| 289 | boff = ti->ti_end % TTYINQ_DATASIZE; |
| 290 | |
| 291 | if (ti->ti_end == 0) { |
| 292 | /* First time we're being used or drained. */ |
| 293 | MPASS(ti->ti_begin == 0); |
| 294 | tib = ti->ti_firstblock; |
| 295 | if (tib == NULL) { |
| 296 | /* Queue has no blocks. */ |
| 297 | break; |
| 298 | } |
| 299 | ti->ti_lastblock = tib; |
| 300 | } else if (boff == 0) { |
| 301 | /* We reached the end of this block on last write. */ |
| 302 | tib = ti->ti_lastblock->tib_next; |
| 303 | if (tib == NULL) { |
| 304 | /* We've reached the watermark. */ |
| 305 | break; |
| 306 | } |
| 307 | ti->ti_lastblock = tib; |
| 308 | } else { |
| 309 | tib = ti->ti_lastblock; |
| 310 | } |
| 311 | |
| 312 | /* Don't copy more than was requested. */ |
| 313 | l = MIN(nbytes, TTYINQ_DATASIZE - boff); |
| 314 | MPASS(l > 0); |
| 315 | memcpy(tib->tib_data + boff, cbuf, l); |
| 316 | |
| 317 | /* Set the quoting bits for the proper region. */ |
| 318 | ttyinq_set_quotes(tib, boff, l, quote); |
| 319 | |
| 320 | cbuf += l; |
| 321 | nbytes -= l; |
| 322 | ti->ti_end += l; |
| 323 | } |
| 324 | |
| 325 | return (cbuf - (const char *)buf); |
| 326 | } |
| 327 | |
| 328 | int |
| 329 | ttyinq_write_nofrag(struct ttyinq *ti, const void *buf, size_t nbytes, int quote) |
no test coverage detected