* The pipe system call for the DTYPE_PIPE type of pipes. If we fail, let * the zone pick up the pieces via pipeclose(). */
| 441 | * the zone pick up the pieces via pipeclose(). |
| 442 | */ |
| 443 | int |
| 444 | kern_pipe(struct thread *td, int fildes[2], int flags, struct filecaps *fcaps1, |
| 445 | struct filecaps *fcaps2) |
| 446 | { |
| 447 | struct file *rf, *wf; |
| 448 | struct pipe *rpipe, *wpipe; |
| 449 | struct pipepair *pp; |
| 450 | int fd, fflags, error; |
| 451 | |
| 452 | error = pipe_paircreate(td, &pp); |
| 453 | if (error != 0) |
| 454 | return (error); |
| 455 | rpipe = &pp->pp_rpipe; |
| 456 | wpipe = &pp->pp_wpipe; |
| 457 | error = falloc_caps(td, &rf, &fd, flags, fcaps1); |
| 458 | if (error) { |
| 459 | pipeclose(rpipe); |
| 460 | pipeclose(wpipe); |
| 461 | return (error); |
| 462 | } |
| 463 | /* An extra reference on `rf' has been held for us by falloc_caps(). */ |
| 464 | fildes[0] = fd; |
| 465 | |
| 466 | fflags = FREAD | FWRITE; |
| 467 | if ((flags & O_NONBLOCK) != 0) |
| 468 | fflags |= FNONBLOCK; |
| 469 | |
| 470 | /* |
| 471 | * Warning: once we've gotten past allocation of the fd for the |
| 472 | * read-side, we can only drop the read side via fdrop() in order |
| 473 | * to avoid races against processes which manage to dup() the read |
| 474 | * side while we are blocked trying to allocate the write side. |
| 475 | */ |
| 476 | finit(rf, fflags, DTYPE_PIPE, rpipe, &pipeops); |
| 477 | error = falloc_caps(td, &wf, &fd, flags, fcaps2); |
| 478 | if (error) { |
| 479 | fdclose(td, rf, fildes[0]); |
| 480 | fdrop(rf, td); |
| 481 | /* rpipe has been closed by fdrop(). */ |
| 482 | pipeclose(wpipe); |
| 483 | return (error); |
| 484 | } |
| 485 | /* An extra reference on `wf' has been held for us by falloc_caps(). */ |
| 486 | finit(wf, fflags, DTYPE_PIPE, wpipe, &pipeops); |
| 487 | fdrop(wf, td); |
| 488 | fildes[1] = fd; |
| 489 | fdrop(rf, td); |
| 490 | |
| 491 | return (0); |
| 492 | } |
| 493 | |
| 494 | #ifdef COMPAT_FREEBSD10 |
| 495 | /* ARGSUSED */ |
no test coverage detected