Author: jkim
Date: Mon Apr 16 21:22:02 2012
New Revision: 234352
URL: http://svn.freebsd.org/changeset/base/234352

Log:
  - Implement pipe2 syscall for Linuxulator.  This syscall appeared in 2.6.27
  but GNU libc used it without checking its kernel version, e. g., Fedora 10.
  - Move pipe(2) implementation for Linuxulator from MD files to MI file,
  sys/compat/linux/linux_file.c.  There is no MD code for this syscall at all.
  - Correct an argument type for pipe() from l_ulong * to l_int *.  Probably
  this was the source of MI/MD confusion.
  
  Reviewed by:  emulation

Modified:
  head/sys/amd64/linux32/linux32_dummy.c
  head/sys/amd64/linux32/linux32_machdep.c
  head/sys/amd64/linux32/syscalls.master
  head/sys/compat/linux/linux_file.c
  head/sys/i386/linux/linux_dummy.c
  head/sys/i386/linux/linux_machdep.c
  head/sys/i386/linux/syscalls.master
  head/sys/kern/sys_pipe.c

Modified: head/sys/amd64/linux32/linux32_dummy.c
==============================================================================
--- head/sys/amd64/linux32/linux32_dummy.c      Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/amd64/linux32/linux32_dummy.c      Mon Apr 16 21:22:02 2012        
(r234352)
@@ -122,7 +122,6 @@ DUMMY(signalfd4);
 DUMMY(eventfd2);
 DUMMY(epoll_create1);
 DUMMY(dup3);
-DUMMY(pipe2);
 DUMMY(inotify_init1);
 /* linux 2.6.30: */
 DUMMY(preadv);

Modified: head/sys/amd64/linux32/linux32_machdep.c
==============================================================================
--- head/sys/amd64/linux32/linux32_machdep.c    Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/amd64/linux32/linux32_machdep.c    Mon Apr 16 21:22:02 2012        
(r234352)
@@ -698,25 +698,6 @@ linux_iopl(struct thread *td, struct lin
 }
 
 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;

Modified: head/sys/amd64/linux32/syscalls.master
==============================================================================
--- head/sys/amd64/linux32/syscalls.master      Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/amd64/linux32/syscalls.master      Mon Apr 16 21:22:02 2012        
(r234352)
@@ -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); }

Modified: head/sys/compat/linux/linux_file.c
==============================================================================
--- head/sys/compat/linux/linux_file.c  Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/compat/linux/linux_file.c  Mon Apr 16 21:22:02 2012        
(r234352)
@@ -69,6 +69,9 @@ __FBSDID("$FreeBSD$");
 #include <compat/linux/linux_util.h>
 #include <compat/linux/linux_file.h>
 
+/* XXX */
+int    do_pipe(struct thread *td, int fildes[2], int flags);
+
 int
 linux_creat(struct thread *td, struct linux_creat_args *args)
 {
@@ -1575,3 +1578,49 @@ linux_fadvise64_64(struct thread *td, st
        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 = do_pipe(td, fildes, 0);
+       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)));
+}

Modified: head/sys/i386/linux/linux_dummy.c
==============================================================================
--- head/sys/i386/linux/linux_dummy.c   Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/i386/linux/linux_dummy.c   Mon Apr 16 21:22:02 2012        
(r234352)
@@ -113,7 +113,6 @@ DUMMY(signalfd4);
 DUMMY(eventfd2);
 DUMMY(epoll_create1);
 DUMMY(dup3);
-DUMMY(pipe2);
 DUMMY(inotify_init1);
 /* linux 2.6.30: */
 DUMMY(preadv);

Modified: head/sys/i386/linux/linux_machdep.c
==============================================================================
--- head/sys/i386/linux/linux_machdep.c Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/i386/linux/linux_machdep.c Mon Apr 16 21:22:02 2012        
(r234352)
@@ -587,25 +587,6 @@ linux_mprotect(struct thread *td, struct
 }
 
 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;

Modified: head/sys/i386/linux/syscalls.master
==============================================================================
--- head/sys/i386/linux/syscalls.master Mon Apr 16 20:41:25 2012        
(r234351)
+++ head/sys/i386/linux/syscalls.master Mon Apr 16 21:22:02 2012        
(r234352)
@@ -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); }

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c    Mon Apr 16 20:41:25 2012        (r234351)
+++ head/sys/kern/sys_pipe.c    Mon Apr 16 21:22:02 2012        (r234352)
@@ -129,6 +129,9 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_page.h>
 #include <vm/uma.h>
 
+/* XXX */
+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 +408,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 +427,7 @@ kern_pipe(struct thread *td, int fildes[
                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 +436,18 @@ kern_pipe(struct thread *td, int fildes[
        /* 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 +456,7 @@ kern_pipe(struct thread *td, int fildes[
                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);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to