Re: compat linux pipe2() circus
Date: Tue, 20 Sep 2011 01:41:35 +0300 From: Paul Irofti p...@irofti.net Linux keeps surprising me everytime! This time its their pipe2 system call which adds flags to the pipe call. Its the unix-ish way apparently to turn pipes into files on a kernel filesystem, or so they claim. Anywho, this fixes glibc pipe2 system calls by wrapping against the regular pipe systemcall if no flags are set and by signaling we don't support that if they are. Okay? Index: linux_ipc.c === RCS file: /cvs/src/sys/compat/linux/linux_ipc.c,v retrieving revision 1.11 diff -u -p -r1.11 linux_ipc.c --- linux_ipc.c 5 Sep 2009 10:28:43 - 1.11 +++ linux_ipc.c 19 Sep 2011 22:37:33 - @@ -719,3 +719,21 @@ linux_shmctl(p, v, retval) } } #endif /* SYSVSHM */ + +int +linux_sys_pipe2(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_pipe2_args *uap = v; + struct sys_pipe_args pargs; + + /* + * We don't really support pipe2, but glibc falls back to pipe + * we return signal that. + * / + if (SCARG(uap, flags) != 0) + return ENOSYS; Don't unimplemented system calls return ENOSYS already? Then the comment makes no sense. Because if glibc falls back on pipe if pipe2 fails, you don't need this code at all. + + /* If no flag is set then the this is a plain pipe call. */ + SCARG(pargs, fdp) = SCARG(uap, fdp); + return sys_pipe(p, pargs, retval); +}
Re: compat linux pipe2() circus
On Tue, Sep 20, 2011 at 09:47:45AM +0200, Mark Kettenis wrote: Date: Tue, 20 Sep 2011 01:41:35 +0300 From: Paul Irofti p...@irofti.net Linux keeps surprising me everytime! This time its their pipe2 system call which adds flags to the pipe call. Its the unix-ish way apparently to turn pipes into files on a kernel filesystem, or so they claim. Anywho, this fixes glibc pipe2 system calls by wrapping against the regular pipe systemcall if no flags are set and by signaling we don't support that if they are. Okay? Index: linux_ipc.c === RCS file: /cvs/src/sys/compat/linux/linux_ipc.c,v retrieving revision 1.11 diff -u -p -r1.11 linux_ipc.c --- linux_ipc.c 5 Sep 2009 10:28:43 - 1.11 +++ linux_ipc.c 19 Sep 2011 22:37:33 - @@ -719,3 +719,21 @@ linux_shmctl(p, v, retval) } } #endif /* SYSVSHM */ + +int +linux_sys_pipe2(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_pipe2_args *uap = v; + struct sys_pipe_args pargs; + + /* +* We don't really support pipe2, but glibc falls back to pipe +* we return signal that. +* / + if (SCARG(uap, flags) != 0) + return ENOSYS; Don't unimplemented system calls return ENOSYS already? Then the comment makes no sense. Because if glibc falls back on pipe if pipe2 fails, you don't need this code at all. The comment is wrong. Glibc invokes the pipe2 syscall when the pipe() function is called. Linux does still have the regular pipe() system call, it's a wrapper around pipe2 (ofcourse that doesn't help us if glibc doesn't use it). + + /* If no flag is set then the this is a plain pipe call. */ + SCARG(pargs, fdp) = SCARG(uap, fdp); + return sys_pipe(p, pargs, retval); +} The comment should change, but I'm fine with the code. -- Ariane
compat linux pipe2() circus
Linux keeps surprising me everytime! This time its their pipe2 system call which adds flags to the pipe call. Its the unix-ish way apparently to turn pipes into files on a kernel filesystem, or so they claim. Anywho, this fixes glibc pipe2 system calls by wrapping against the regular pipe systemcall if no flags are set and by signaling we don't support that if they are. Okay? Index: linux_ipc.c === RCS file: /cvs/src/sys/compat/linux/linux_ipc.c,v retrieving revision 1.11 diff -u -p -r1.11 linux_ipc.c --- linux_ipc.c 5 Sep 2009 10:28:43 - 1.11 +++ linux_ipc.c 19 Sep 2011 22:37:33 - @@ -719,3 +719,21 @@ linux_shmctl(p, v, retval) } } #endif /* SYSVSHM */ + +int +linux_sys_pipe2(struct proc *p, void *v, register_t *retval) +{ + struct linux_sys_pipe2_args *uap = v; + struct sys_pipe_args pargs; + + /* +* We don't really support pipe2, but glibc falls back to pipe +* we return signal that. +* / + if (SCARG(uap, flags) != 0) + return ENOSYS; + + /* If no flag is set then the this is a plain pipe call. */ + SCARG(pargs, fdp) = SCARG(uap, fdp); + return sys_pipe(p, pargs, retval); +} Index: linux_syscall.h === RCS file: /cvs/src/sys/compat/linux/linux_syscall.h,v retrieving revision 1.66 diff -u -p -r1.66 linux_syscall.h --- linux_syscall.h 19 Sep 2011 14:33:40 - 1.66 +++ linux_syscall.h 19 Sep 2011 22:37:34 - @@ -1,10 +1,10 @@ -/* $OpenBSD: linux_syscall.h,v 1.66 2011/09/19 14:33:40 pirofti Exp $ */ +/* $OpenBSD$ */ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created fromOpenBSD: syscalls.master,v 1.62 2011/09/18 02:23:18 pirofti Exp + * created fromOpenBSD: syscalls.master,v 1.63 2011/09/19 14:33:14 pirofti Exp */ /* syscall: syscall ret: int args: */ @@ -747,5 +747,8 @@ /* syscall: get_robust_list ret: int args: int struct linux_robust_list_head ** size_t * */ #defineLINUX_SYS_get_robust_list 312 + +/* syscall: pipe2 ret: int args: int * int */ +#defineLINUX_SYS_pipe2 331 #defineLINUX_SYS_MAXSYSCALL338 Index: linux_syscallargs.h === RCS file: /cvs/src/sys/compat/linux/linux_syscallargs.h,v retrieving revision 1.68 diff -u -p -r1.68 linux_syscallargs.h --- linux_syscallargs.h 19 Sep 2011 14:33:40 - 1.68 +++ linux_syscallargs.h 19 Sep 2011 22:37:35 - @@ -1,10 +1,10 @@ -/* $OpenBSD: linux_syscallargs.h,v 1.68 2011/09/19 14:33:40 pirofti Exp $ */ +/* $OpenBSD$ */ /* * System call argument lists. * * DO NOT EDIT-- this file is automatically generated. - * created fromOpenBSD: syscalls.master,v 1.62 2011/09/18 02:23:18 pirofti Exp + * created fromOpenBSD: syscalls.master,v 1.63 2011/09/19 14:33:14 pirofti Exp */ #ifdef syscallarg @@ -610,6 +610,11 @@ struct linux_sys_get_robust_list_args { syscallarg(size_t *) len; }; +struct linux_sys_pipe2_args { + syscallarg(int *) fdp; + syscallarg(int) flags; +}; + /* * System call prototypes. */ @@ -876,3 +881,4 @@ int linux_sys_clock_gettime(struct proc intlinux_sys_clock_getres(struct proc *, void *, register_t *); intlinux_sys_set_robust_list(struct proc *, void *, register_t *); intlinux_sys_get_robust_list(struct proc *, void *, register_t *); +intlinux_sys_pipe2(struct proc *, void *, register_t *); Index: linux_syscalls.c === RCS file: /cvs/src/sys/compat/linux/linux_syscalls.c,v retrieving revision 1.66 diff -u -p -r1.66 linux_syscalls.c --- linux_syscalls.c19 Sep 2011 14:33:40 - 1.66 +++ linux_syscalls.c19 Sep 2011 22:37:35 - @@ -1,10 +1,10 @@ -/* $OpenBSD: linux_syscalls.c,v 1.66 2011/09/19 14:33:40 pirofti Exp $ */ +/* $OpenBSD$ */ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created fromOpenBSD: syscalls.master,v 1.62 2011/09/18 02:23:18 pirofti Exp + * created fromOpenBSD: syscalls.master,v 1.63 2011/09/19 14:33:14 pirofti Exp */ char *linux_syscallnames[] = { @@ -359,7 +359,7 @@ char *linux_syscallnames[] = { #328 (unimplemented eventfd2),/* 328 = unimplemented eventfd2 */ #329 (unimplemented epoll_create1), /* 329 = unimplemented epoll_create1 */ #330 (unimplemented dup3),/* 330 = unimplemented dup3 */ - #331 (unimplemented pipe2), /* 331 = unimplemented pipe2 */ + pipe2,/* 331 = pipe2 */ #332 (unimplemented inotify_init1), /* 332 = unimplemented inotify_init1 */ #333 (unimplemented preadv),
Re: compat linux pipe2() circus
On Tue, Sep 20, 2011 at 01:41:35AM +0300, Paul Irofti wrote: This time its their pipe2 system call which adds flags to the pipe call. Its the unix-ish way apparently to turn pipes into files on a kernel filesystem, or so they claim. No, the idea is to make it possible to set O_CLOEXEC atomically. Of course, the pipe2 system call as implemented in Linux is kind of messed up, since the flag attribute applies to both sides of the pipe. The use cases of pipes that don't involve exec are limited (using pipes to terminate poll/select loops from signal handles, communication between a fork'd hord of children), so I am kind of waiting for pipe3 to appear... Joerg
Re: compat linux pipe2() circus
On Mon, Sep 19, 2011 at 4:22 PM, Joerg Sonnenberger jo...@britannica.bec.de wrote: No, the idea is to make it possible to set O_CLOEXEC atomically. Of course, the pipe2 system call as implemented in Linux is kind of messed up, since the flag attribute applies to both sides of the pipe. If you need O_CLOEXEC, you want it to apply to both fds anyway, even if you plan on passing one fd to a child process. You just turn the appropriate cloexec flag back off after calling fork(2).