Index: sys/amd64/linux32/linux32_machdep.c =================================================================== --- sys/amd64/linux32/linux32_machdep.c (revision 234112) +++ sys/amd64/linux32/linux32_machdep.c (working copy) @@ -698,25 +698,6 @@ linux_iopl(struct thread *td, struct linux_iopl_ar } int -linux_pipe(struct thread *td, struct linux_pipe_args *args) -{ - int error; - int fildes[2]; - -#ifdef DEBUG - if (ldebug(pipe)) - printf(ARGS(pipe, "*")); -#endif - - error = kern_pipe(td, fildes); - if (error) - return (error); - - /* XXX: Close descriptors on error. */ - return (copyout(fildes, args->pipefds, sizeof fildes)); -} - -int linux_sigaction(struct thread *td, struct linux_sigaction_args *args) { l_osigaction_t osa; Index: sys/amd64/linux32/linux32_systrace_args.c =================================================================== --- sys/amd64/linux32/linux32_systrace_args.c (revision 234112) +++ sys/amd64/linux32/linux32_systrace_args.c (working copy) @@ -287,7 +287,7 @@ systrace_args(int sysnum, void *params, uint64_t * /* linux_pipe */ case 42: { struct linux_pipe_args *p = params; - uarg[0] = (intptr_t) p->pipefds; /* l_ulong * */ + uarg[0] = (intptr_t) p->pipefds; /* l_int * */ *n_args = 1; break; } @@ -2172,7 +2172,10 @@ systrace_args(int sysnum, void *params, uint64_t * } /* linux_pipe2 */ case 331: { - *n_args = 0; + struct linux_pipe2_args *p = params; + uarg[0] = (intptr_t) p->pipefds; /* l_int * */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; break; } /* linux_inotify_init1 */ @@ -2689,7 +2692,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, cha case 42: switch(ndx) { case 0: - p = "l_ulong *"; + p = "l_int *"; break; default: break; @@ -5368,6 +5371,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, cha break; /* linux_pipe2 */ case 331: + switch(ndx) { + case 0: + p = "l_int *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; break; /* linux_inotify_init1 */ case 332: @@ -6621,6 +6634,9 @@ systrace_return_setargdesc(int sysnum, int ndx, ch case 330: /* linux_pipe2 */ case 331: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_inotify_init1 */ case 332: /* linux_preadv */ Index: sys/amd64/linux32/syscalls.master =================================================================== --- sys/amd64/linux32/syscalls.master (revision 234112) +++ sys/amd64/linux32/syscalls.master (working copy) @@ -95,7 +95,7 @@ 39 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); } 40 AUE_RMDIR STD { int linux_rmdir(char *path); } 41 AUE_DUP NOPROTO { int dup(u_int fd); } -42 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); } +42 AUE_PIPE STD { int linux_pipe(l_int *pipefds); } 43 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk(l_ulong dsend); } @@ -536,7 +536,7 @@ 328 AUE_NULL STD { int linux_eventfd2(void); } 329 AUE_NULL STD { int linux_epoll_create1(void); } 330 AUE_NULL STD { int linux_dup3(void); } -331 AUE_NULL STD { int linux_pipe2(void); } +331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; linux 2.6.30: 333 AUE_NULL STD { int linux_preadv(void); } Index: sys/amd64/linux32/linux32_sysent.c =================================================================== --- sys/amd64/linux32/linux32_sysent.c (revision 234112) +++ sys/amd64/linux32/linux32_sysent.c (working copy) @@ -350,7 +350,7 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ - { 0, (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ + { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */ { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */ { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */ Index: sys/amd64/linux32/linux32_dummy.c =================================================================== --- sys/amd64/linux32/linux32_dummy.c (revision 234112) +++ sys/amd64/linux32/linux32_dummy.c (working copy) @@ -122,7 +122,6 @@ DUMMY(signalfd4); DUMMY(eventfd2); DUMMY(epoll_create1); DUMMY(dup3); -DUMMY(pipe2); DUMMY(inotify_init1); /* linux 2.6.30: */ DUMMY(preadv); Index: sys/amd64/linux32/linux32_proto.h =================================================================== --- sys/amd64/linux32/linux32_proto.h (revision 234112) +++ sys/amd64/linux32/linux32_proto.h (working copy) @@ -153,7 +153,7 @@ struct linux_rmdir_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; }; struct linux_pipe_args { - char pipefds_l_[PADL_(l_ulong *)]; l_ulong * pipefds; char pipefds_r_[PADR_(l_ulong *)]; + char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; }; struct linux_times_args { char buf_l_[PADL_(struct l_times_argv *)]; struct l_times_argv * buf; char buf_r_[PADR_(struct l_times_argv *)]; @@ -1046,7 +1046,8 @@ struct linux_dup3_args { register_t dummy; }; struct linux_pipe2_args { - register_t dummy; + char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_inotify_init1_args { register_t dummy; Index: sys/compat/linux/linux_file.c =================================================================== --- sys/compat/linux/linux_file.c (revision 234112) +++ sys/compat/linux/linux_file.c (working copy) @@ -69,6 +69,8 @@ __FBSDID("$FreeBSD$"); #include #include +extern int do_pipe(struct thread *td, int fildes[2], int flags); + int linux_creat(struct thread *td, struct linux_creat_args *args) { @@ -1575,3 +1577,49 @@ linux_fadvise64_64(struct thread *td, struct linux return (kern_posix_fadvise(td, args->fd, args->offset, args->len, advice)); } + +int +linux_pipe(struct thread *td, struct linux_pipe_args *args) +{ + int fildes[2]; + int error; + +#ifdef DEBUG + if (ldebug(pipe)) + printf(ARGS(pipe, "*")); +#endif + + error = kern_pipe(td, fildes); + if (error) + return (error); + + /* XXX: Close descriptors on error. */ + return (copyout(fildes, args->pipefds, sizeof(fildes))); +} + +int +linux_pipe2(struct thread *td, struct linux_pipe2_args *args) +{ + int fildes[2]; + int error, flags; + +#ifdef DEBUG + if (ldebug(pipe2)) + printf(ARGS(pipe2, "*, %d"), args->flags); +#endif + + if ((args->flags & ~(LINUX_O_NONBLOCK | LINUX_O_CLOEXEC)) != 0) + return (EINVAL); + + flags = 0; + if ((args->flags & LINUX_O_NONBLOCK) != 0) + flags |= O_NONBLOCK; + if ((args->flags & LINUX_O_CLOEXEC) != 0) + flags |= O_CLOEXEC; + error = do_pipe(td, fildes, flags); + if (error) + return (error); + + /* XXX: Close descriptors on error. */ + return (copyout(fildes, args->pipefds, sizeof(fildes))); +} Index: sys/i386/linux/linux_sysent.c =================================================================== --- sys/i386/linux/linux_sysent.c (revision 234112) +++ sys/i386/linux/linux_sysent.c (working copy) @@ -349,7 +349,7 @@ struct sysent linux_sysent[] = { { 0, (sy_call_t *)linux_eventfd2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 328 = linux_eventfd2 */ { 0, (sy_call_t *)linux_epoll_create1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 329 = linux_epoll_create1 */ { 0, (sy_call_t *)linux_dup3, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 330 = linux_dup3 */ - { 0, (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ + { AS(linux_pipe2_args), (sy_call_t *)linux_pipe2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 331 = linux_pipe2 */ { 0, (sy_call_t *)linux_inotify_init1, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 332 = linux_inotify_init1 */ { 0, (sy_call_t *)linux_preadv, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 333 = linux_preadv */ { 0, (sy_call_t *)linux_pwritev, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 334 = linux_pwritev */ Index: sys/i386/linux/linux_machdep.c =================================================================== --- sys/i386/linux/linux_machdep.c (revision 234112) +++ sys/i386/linux/linux_machdep.c (working copy) @@ -587,25 +587,6 @@ linux_mprotect(struct thread *td, struct linux_mpr } int -linux_pipe(struct thread *td, struct linux_pipe_args *args) -{ - int error; - int fildes[2]; - -#ifdef DEBUG - if (ldebug(pipe)) - printf(ARGS(pipe, "*")); -#endif - - error = kern_pipe(td, fildes); - if (error) - return (error); - - /* XXX: Close descriptors on error. */ - return (copyout(fildes, args->pipefds, sizeof fildes)); -} - -int linux_ioperm(struct thread *td, struct linux_ioperm_args *args) { int error; Index: sys/i386/linux/linux_systrace_args.c =================================================================== --- sys/i386/linux/linux_systrace_args.c (revision 234112) +++ sys/i386/linux/linux_systrace_args.c (working copy) @@ -295,7 +295,7 @@ systrace_args(int sysnum, void *params, uint64_t * /* linux_pipe */ case 42: { struct linux_pipe_args *p = params; - uarg[0] = (intptr_t) p->pipefds; /* l_ulong * */ + uarg[0] = (intptr_t) p->pipefds; /* l_int * */ *n_args = 1; break; } @@ -2263,7 +2263,10 @@ systrace_args(int sysnum, void *params, uint64_t * } /* linux_pipe2 */ case 331: { - *n_args = 0; + struct linux_pipe2_args *p = params; + uarg[0] = (intptr_t) p->pipefds; /* l_int * */ + iarg[1] = p->flags; /* l_int */ + *n_args = 2; break; } /* linux_inotify_init1 */ @@ -2793,7 +2796,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, cha case 42: switch(ndx) { case 0: - p = "l_ulong *"; + p = "l_int *"; break; default: break; @@ -5664,6 +5667,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, cha break; /* linux_pipe2 */ case 331: + switch(ndx) { + case 0: + p = "l_int *"; + break; + case 1: + p = "l_int"; + break; + default: + break; + }; break; /* linux_inotify_init1 */ case 332: @@ -6979,6 +6992,9 @@ systrace_return_setargdesc(int sysnum, int ndx, ch case 330: /* linux_pipe2 */ case 331: + if (ndx == 0 || ndx == 1) + p = "int"; + break; /* linux_inotify_init1 */ case 332: /* linux_preadv */ Index: sys/i386/linux/syscalls.master =================================================================== --- sys/i386/linux/syscalls.master (revision 234112) +++ sys/i386/linux/syscalls.master (working copy) @@ -95,7 +95,7 @@ 39 AUE_MKDIR STD { int linux_mkdir(char *path, l_int mode); } 40 AUE_RMDIR STD { int linux_rmdir(char *path); } 41 AUE_DUP NOPROTO { int dup(u_int fd); } -42 AUE_PIPE STD { int linux_pipe(l_ulong *pipefds); } +42 AUE_PIPE STD { int linux_pipe(l_int *pipefds); } 43 AUE_NULL STD { int linux_times(struct l_times_argv *buf); } 44 AUE_NULL UNIMPL prof 45 AUE_NULL STD { int linux_brk(l_ulong dsend); } @@ -546,7 +546,7 @@ 328 AUE_NULL STD { int linux_eventfd2(void); } 329 AUE_NULL STD { int linux_epoll_create1(void); } 330 AUE_NULL STD { int linux_dup3(void); } -331 AUE_NULL STD { int linux_pipe2(void); } +331 AUE_NULL STD { int linux_pipe2(l_int *pipefds, l_int flags); } 332 AUE_NULL STD { int linux_inotify_init1(void); } ; linux 2.6.30: 333 AUE_NULL STD { int linux_preadv(void); } Index: sys/i386/linux/linux_dummy.c =================================================================== --- sys/i386/linux/linux_dummy.c (revision 234112) +++ sys/i386/linux/linux_dummy.c (working copy) @@ -113,7 +113,6 @@ DUMMY(signalfd4); DUMMY(eventfd2); DUMMY(epoll_create1); DUMMY(dup3); -DUMMY(pipe2); DUMMY(inotify_init1); /* linux 2.6.30: */ DUMMY(preadv); Index: sys/i386/linux/linux_proto.h =================================================================== --- sys/i386/linux/linux_proto.h (revision 234112) +++ sys/i386/linux/linux_proto.h (working copy) @@ -157,7 +157,7 @@ struct linux_rmdir_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; }; struct linux_pipe_args { - char pipefds_l_[PADL_(l_ulong *)]; l_ulong * pipefds; char pipefds_r_[PADR_(l_ulong *)]; + char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; }; struct linux_times_args { char buf_l_[PADL_(struct l_times_argv *)]; struct l_times_argv * buf; char buf_r_[PADR_(struct l_times_argv *)]; @@ -1065,7 +1065,8 @@ struct linux_dup3_args { register_t dummy; }; struct linux_pipe2_args { - register_t dummy; + char pipefds_l_[PADL_(l_int *)]; l_int * pipefds; char pipefds_r_[PADR_(l_int *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; }; struct linux_inotify_init1_args { register_t dummy; Index: sys/kern/sys_pipe.c =================================================================== --- sys/kern/sys_pipe.c (revision 234112) +++ sys/kern/sys_pipe.c (working copy) @@ -129,6 +129,8 @@ __FBSDID("$FreeBSD$"); #include #include +int do_pipe(struct thread *td, int fildes[2], int flags); + /* * Use this define if you want to disable *fancy* VM things. Expect an * approx 30% decrease in transfer rate. This could be useful for @@ -405,11 +407,18 @@ pipe_dtor(struct pipe *dpipe) int kern_pipe(struct thread *td, int fildes[2]) { + + return (do_pipe(td, fildes, 0)); +} + +int +do_pipe(struct thread *td, int fildes[2], int flags) +{ struct filedesc *fdp; struct file *rf, *wf; struct pipe *rpipe, *wpipe; struct pipepair *pp; - int fd, error; + int fd, fflags, error; fdp = td->td_proc->p_fd; error = pipe_paircreate(td, &pp); @@ -417,7 +426,7 @@ kern_pipe(struct thread *td, int fildes[2]) return (error); rpipe = &pp->pp_rpipe; wpipe = &pp->pp_wpipe; - error = falloc(td, &rf, &fd, 0); + error = falloc(td, &rf, &fd, flags); if (error) { pipeclose(rpipe); pipeclose(wpipe); @@ -426,14 +435,18 @@ kern_pipe(struct thread *td, int fildes[2]) /* An extra reference on `rf' has been held for us by falloc(). */ fildes[0] = fd; + fflags = FREAD | FWRITE; + if ((flags & O_NONBLOCK) != 0) + fflags |= FNONBLOCK; + /* * Warning: once we've gotten past allocation of the fd for the * read-side, we can only drop the read side via fdrop() in order * to avoid races against processes which manage to dup() the read * side while we are blocked trying to allocate the write side. */ - finit(rf, FREAD | FWRITE, DTYPE_PIPE, rpipe, &pipeops); - error = falloc(td, &wf, &fd, 0); + finit(rf, fflags, DTYPE_PIPE, rpipe, &pipeops); + error = falloc(td, &wf, &fd, flags); if (error) { fdclose(fdp, rf, fildes[0], td); fdrop(rf, td); @@ -442,7 +455,7 @@ kern_pipe(struct thread *td, int fildes[2]) return (error); } /* An extra reference on `wf' has been held for us by falloc(). */ - finit(wf, FREAD | FWRITE, DTYPE_PIPE, wpipe, &pipeops); + finit(wf, fflags, DTYPE_PIPE, wpipe, &pipeops); fdrop(wf, td); fildes[1] = fd; fdrop(rf, td);