* Common code for writev and pwritev that writes data to * a file using the passed in uio, offset, and flags. */
| 544 | * a file using the passed in uio, offset, and flags. |
| 545 | */ |
| 546 | static int |
| 547 | dofilewrite(struct thread *td, int fd, struct file *fp, struct uio *auio, |
| 548 | off_t offset, int flags) |
| 549 | { |
| 550 | ssize_t cnt; |
| 551 | int error; |
| 552 | #ifdef KTRACE |
| 553 | struct uio *ktruio = NULL; |
| 554 | #endif |
| 555 | |
| 556 | AUDIT_ARG_FD(fd); |
| 557 | auio->uio_rw = UIO_WRITE; |
| 558 | auio->uio_td = td; |
| 559 | auio->uio_offset = offset; |
| 560 | #ifdef KTRACE |
| 561 | if (KTRPOINT(td, KTR_GENIO)) |
| 562 | ktruio = cloneuio(auio); |
| 563 | #endif |
| 564 | cnt = auio->uio_resid; |
| 565 | if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) { |
| 566 | if (auio->uio_resid != cnt && (error == ERESTART || |
| 567 | error == EINTR || error == EWOULDBLOCK)) |
| 568 | error = 0; |
| 569 | /* Socket layer is responsible for issuing SIGPIPE. */ |
| 570 | if (fp->f_type != DTYPE_SOCKET && error == EPIPE) { |
| 571 | PROC_LOCK(td->td_proc); |
| 572 | tdsignal(td, SIGPIPE); |
| 573 | PROC_UNLOCK(td->td_proc); |
| 574 | } |
| 575 | } |
| 576 | cnt -= auio->uio_resid; |
| 577 | #ifdef KTRACE |
| 578 | if (ktruio != NULL) { |
| 579 | ktruio->uio_resid = cnt; |
| 580 | ktrgenio(fd, UIO_WRITE, ktruio, error); |
| 581 | } |
| 582 | #endif |
| 583 | td->td_retval[0] = cnt; |
| 584 | return (error); |
| 585 | } |
| 586 | |
| 587 | /* |
| 588 | * Truncate a file given a file descriptor. |
no test coverage detected