| 277 | } |
| 278 | |
| 279 | size_t |
| 280 | ttyoutq_write(struct ttyoutq *to, const void *buf, size_t nbytes) |
| 281 | { |
| 282 | const char *cbuf = buf; |
| 283 | struct ttyoutq_block *tob; |
| 284 | unsigned int boff; |
| 285 | size_t l; |
| 286 | |
| 287 | while (nbytes > 0) { |
| 288 | boff = to->to_end % TTYOUTQ_DATASIZE; |
| 289 | |
| 290 | if (to->to_end == 0) { |
| 291 | /* First time we're being used or drained. */ |
| 292 | MPASS(to->to_begin == 0); |
| 293 | tob = to->to_firstblock; |
| 294 | if (tob == NULL) { |
| 295 | /* Queue has no blocks. */ |
| 296 | break; |
| 297 | } |
| 298 | to->to_lastblock = tob; |
| 299 | } else if (boff == 0) { |
| 300 | /* We reached the end of this block on last write. */ |
| 301 | tob = to->to_lastblock->tob_next; |
| 302 | if (tob == NULL) { |
| 303 | /* We've reached the watermark. */ |
| 304 | break; |
| 305 | } |
| 306 | to->to_lastblock = tob; |
| 307 | } else { |
| 308 | tob = to->to_lastblock; |
| 309 | } |
| 310 | |
| 311 | /* Don't copy more than was requested. */ |
| 312 | l = MIN(nbytes, TTYOUTQ_DATASIZE - boff); |
| 313 | MPASS(l > 0); |
| 314 | memcpy(tob->tob_data + boff, cbuf, l); |
| 315 | |
| 316 | cbuf += l; |
| 317 | nbytes -= l; |
| 318 | to->to_end += l; |
| 319 | } |
| 320 | |
| 321 | return (cbuf - (const char *)buf); |
| 322 | } |
| 323 | |
| 324 | int |
| 325 | ttyoutq_write_nofrag(struct ttyoutq *to, const void *buf, size_t nbytes) |
no test coverage detected