From 473547c77745df8bd261b3db3361fb1373860700 Mon Sep 17 00:00:00 2001 From: Thomas Veerman Date: Mon, 25 Feb 2013 14:45:22 +0000 Subject: [PATCH] VFS: implement pipe2 Change-Id: Iedc8042dd73a903456b25ba665d12577f5589ca2 --- distrib/sets/lists/minix/mi | 1 + include/minix/callnr.h | 1 + include/unistd.h | 2 +- lib/libc/Makefile | 2 +- lib/libc/include/namespace.h | 1 + lib/libc/sys-minix/pipe.c | 28 +++++++++--- lib/libc/sys/Makefile.inc | 17 ++++++- man/man2/Makefile | 2 +- man/man2/pipe.2 | 89 ------------------------------------ servers/vfs/README | 2 +- servers/vfs/param.h | 1 + servers/vfs/pipe.c | 52 ++++++++++++++++++--- servers/vfs/proto.h | 1 + servers/vfs/table.c | 2 +- 14 files changed, 91 insertions(+), 110 deletions(-) delete mode 100644 man/man2/pipe.2 diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 491b911fb..8d0466fa6 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -1476,6 +1476,7 @@ ./usr/man/man2/open.2 minix-sys ./usr/man/man2/pause.2 minix-sys ./usr/man/man2/pipe.2 minix-sys +./usr/man/man2/pipe2.2 minix-sys ./usr/man/man2/ptrace.2 minix-sys ./usr/man/man2/read.2 minix-sys ./usr/man/man2/readlink.2 minix-sys diff --git a/include/minix/callnr.h b/include/minix/callnr.h index 6f145cf88..7df56e02e 100644 --- a/include/minix/callnr.h +++ b/include/minix/callnr.h @@ -55,6 +55,7 @@ #define IOCTL 54 #define FCNTL 55 #define FS_READY 57 +#define PIPE2 58 #define EXEC 59 #define UMASK 60 #define CHROOT 61 diff --git a/include/unistd.h b/include/unistd.h index 0ffba9f24..c2e93a087 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -377,8 +377,8 @@ int initgroups(const char *, gid_t); int iruserok(uint32_t, int, const char *, const char *); int issetugid(void); int nfssvc(int, void *); -#ifndef __minix int pipe2(int *, int); +#ifndef __minix int profil(char *, size_t, u_long, u_int); #endif /* !__minix */ #ifndef __PSIGNAL_DECLARED diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 6dc6106be..6c5bbf8ea 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -106,8 +106,8 @@ SUBDIR+= pkgconfig .include "${.CURDIR}/sys-minix/Makefile.inc" .else .include "${.CURDIR}/tls/Makefile.inc" -.include "${.CURDIR}/sys/Makefile.inc" .endif +.include "${.CURDIR}/sys/Makefile.inc" .include "${.CURDIR}/uuid/Makefile.inc" .if (${MKYP} != "no") .include "${.CURDIR}/yp/Makefile.inc" diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h index 71848e06e..84d39338a 100644 --- a/lib/libc/include/namespace.h +++ b/lib/libc/include/namespace.h @@ -57,6 +57,7 @@ #define inet_aton _inet_aton #define inet_pton _inet_pton #define pipe _pipe +#define pipe2 _pipe2 #define sbrk _sbrk #define strerror_r _strerror_r #define strlcat _strlcat diff --git a/lib/libc/sys-minix/pipe.c b/lib/libc/sys-minix/pipe.c index 9f883885c..fa71e4e65 100644 --- a/lib/libc/sys-minix/pipe.c +++ b/lib/libc/sys-minix/pipe.c @@ -6,15 +6,29 @@ #ifdef __weak_alias __weak_alias(pipe, _pipe) +__weak_alias(pipe2, _pipe2) #endif -int pipe(fild) -int fild[2]; +int +pipe(int fild[2]) { - message m; + message m; - if (_syscall(VFS_PROC_NR, PIPE, &m) < 0) return(-1); - fild[0] = m.m1_i1; - fild[1] = m.m1_i2; - return(0); + if (_syscall(VFS_PROC_NR, PIPE, &m) < 0) return(-1); + fild[0] = m.m1_i1; + fild[1] = m.m1_i2; + return(0); +} + +int +pipe2(int fild[2], int flags) +{ + message m; + + m.m1_i3 = flags; + + if (_syscall(VFS_PROC_NR, PIPE2, &m) < 0) return(-1); + fild[0] = m.m1_i1; + fild[1] = m.m1_i2; + return(0); } diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index d591e23a9..3d6d088ee 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,6 +1,9 @@ # $NetBSD: Makefile.inc,v 1.217 2012/10/02 01:46:40 christos Exp $ # @(#)Makefile.inc 8.3 (Berkeley) 10/24/94 +.if defined(__MINIX) +.PATH: ${.CURDIR}/sys +.else # sys sources .PATH: ${ARCHDIR}/sys ${.CURDIR}/sys @@ -215,7 +218,9 @@ LintSysPseudoNoerr.c: ${LIBCDIR}/sys/makelintstub \ ${_MKTARGET_CREATE} CPP=${CPP:Q} ${HOST_SH} ${LIBCDIR}/sys/makelintstub -o ${.TARGET} -p \ -s ${DESTDIR}/usr/include/sys/syscall.h ${PSEUDONOERR} +.endif # !defined(__MINIX) +.if !defined(__MINIX) MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 \ chflags.2 chmod.2 chown.2 chroot.2 clock_settime.2 clone.2 close.2 \ connect.2 dup.2 execve.2 _exit.2 extattr_get_file.2 \ @@ -237,8 +242,12 @@ MAN+= accept.2 access.2 acct.2 adjtime.2 bind.2 brk.2 chdir.2 \ madvise.2 mincore.2 minherit.2 mlock.2 mlockall.2 mmap.2 modctl.2 \ mount.2 \ mprotect.2 mremap.2 msgctl.2 msgget.2 msgrcv.2 msgsnd.2 msync.2 \ - munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2 \ - pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \ + munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 pathconf.2 pipe.2 +.else +MAN+= pipe.2 +.endif # !defined(__MINIX) +.if !defined(__MINIX) +MAN+= pmc_control.2 poll.2 posix_fadvise.2 profil.2 ptrace.2 __quotactl.2 \ rasctl.2 read.2 readlink.2 \ reboot.2 recv.2 rename.2 revoke.2 rmdir.2 \ select.2 semctl.2 \ @@ -325,6 +334,10 @@ MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2 MLINKS+=utimes.2 futimens.2 utimes.2 utimensat.2 MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 MLINKS+=write.2 writev.2 write.2 pwrite.2 write.2 pwritev.2 +.else MLINKS+=pipe.2 pipe2.2 +.endif # !defined(__MINIX) +.if !defined(__MINIX) MLINKS+=accept.2 paccept.2 MLINKS+=nanosleep.2 clock_nanosleep.2 +.endif # !defined(__MINIX) diff --git a/man/man2/Makefile b/man/man2/Makefile index 44f54aba2..edbfe5852 100644 --- a/man/man2/Makefile +++ b/man/man2/Makefile @@ -3,7 +3,7 @@ MAN= accept.2 access.2 alarm.2 bind.2 brk.2 chdir.2 chmod.2 chown.2 \ fork.2 getgid.2 getitimer.2 getnucred.2 getpeereid.2 \ getpeername.2 getpid.2 getpriority.2 getsockname.2 getsockopt.2 \ gettimeofday.2 getuid.2 intro.2 ioctl.2 kill.2 link.2 listen.2 \ - lseek.2 mkdir.2 mknod.2 mount.2 open.2 pause.2 pipe.2 ptrace.2 \ + lseek.2 mkdir.2 mknod.2 mount.2 open.2 pause.2 ptrace.2 \ read.2 readlink.2 reboot.2 recv.2 recvfrom.2 recvmsg.2 rename.2 \ rmdir.2 select.2 send.2 sendmsg.2 sendto.2 setsid.2 \ setsockopt.2 setuid.2 shutdown.2 sigaction.2 sigpending.2 \ diff --git a/man/man2/pipe.2 b/man/man2/pipe.2 deleted file mode 100644 index 8154eae3c..000000000 --- a/man/man2/pipe.2 +++ /dev/null @@ -1,89 +0,0 @@ -.\" Copyright (c) 1980 Regents of the University of California. -.\" All rights reserved. The Berkeley software License Agreement -.\" specifies the terms and conditions for redistribution. -.\" -.\" @(#)pipe.2 6.2 (Berkeley) 8/26/85 -.\" -.TH PIPE 2 "August 26, 1985" -.UC 4 -.SH NAME -pipe \- create an interprocess communication channel -.SH SYNOPSIS -.nf -.ft B -#include - -int pipe(int \fIfildes\fP[2]) -.fi -.ft R -.SH DESCRIPTION -The -.B pipe -system call -creates an I/O mechanism called a pipe. -The file descriptors returned can -be used in read and write operations. -When the pipe is written using the descriptor -.IR fildes [1] -up to PIPE_MAX bytes of data are buffered -before the writing process is suspended. -A read using the descriptor -.IR fildes [0] -will pick up the data. -.PP -PIPE_MAX equals 7168 under MINIX 3, but note that most systems use 4096. -.PP -It is assumed that after the -pipe has been set up, -two (or more) -cooperating processes -(created by subsequent -.B fork -calls) -will pass data through the -pipe with -.B read -and -.B write -calls. -.PP -The shell has a syntax -to set up a linear array of processes -connected by pipes. -.PP -Read calls on an empty -pipe (no buffered data) with only one end -(all write file descriptors closed) -returns an end-of-file. -.PP -The signal SIGPIPE is generated if a write on a pipe with only one end -is attempted. -.SH "RETURN VALUE -The function value zero is returned if the -pipe was created; \-1 if an error occurred. -.SH ERRORS -The \fBpipe\fP call will fail if: -.TP 15 -[EMFILE] -Too many descriptors are active. -.TP 15 -[ENFILE] -The system file table is full. -.TP 15 -[ENOSPC] -The pipe file system (usually the root file system) has no free inodes. -.TP 15 -[EFAULT] -The \fIfildes\fP buffer is in an invalid area of the process's address -space. -.SH "SEE ALSO" -.BR sh (1), -.BR read (2), -.BR write (2), -.BR fork (2). -.SH NOTES -Writes may return ENOSPC errors if no pipe data can be buffered, because -the pipe file system is full. -.SH BUGS -Should more than PIPE_MAX bytes be necessary in any -pipe among a loop of processes, deadlock will occur. diff --git a/servers/vfs/README b/servers/vfs/README index 7ded7c3e0..3b0ebd35e 100644 --- a/servers/vfs/README +++ b/servers/vfs/README @@ -538,7 +538,7 @@ the filp, the vnode remains locked, the soft lock is removed, and the filp mutex is released. Note that this scheme does not violate the locking order; the vnode is (already) locked before the filp. -A similar problem arises with do_pipe. In this case we obtain a new vnode +A similar problem arises with create_pipe. In this case we obtain a new vnode object, lock it, and obtain two new, locked, filp objects. If everything works out and the filp objects are linked to the same vnode, we run into trouble when unlocking both filps. The first filp being unlocked would work; the diff --git a/servers/vfs/param.h b/servers/vfs/param.h index ea05621bb..212676621 100644 --- a/servers/vfs/param.h +++ b/servers/vfs/param.h @@ -31,6 +31,7 @@ #define offset_high m2_l2 #define ctl_req m4_l1 #define mount_flags m1_i3 +#define pipe_flags m1_i3 #define request m1_i2 #define sig m1_i2 #define endpt1 m1_i1 diff --git a/servers/vfs/pipe.c b/servers/vfs/pipe.c index 9c7e230a5..c1281393e 100644 --- a/servers/vfs/pipe.c +++ b/servers/vfs/pipe.c @@ -34,18 +34,55 @@ #include "vnode.h" #include "vmnt.h" +static int create_pipe(int fil_des[2], int flags); /*===========================================================================* * do_pipe * *===========================================================================*/ int do_pipe() { -/* Perform the pipe(fil_des) system call. */ +/* Perform the pipe(fil_des[2]) system call. */ + int r; + int fil_des[2]; /* reply goes here */ + + r = create_pipe(fil_des, 0 /* no flags */); + if (r == OK) { + m_out.reply_i1 = fil_des[0]; + m_out.reply_i2 = fil_des[1]; + } + + return r; +} + +/*===========================================================================* + * do_pipe2 * + *===========================================================================*/ +int do_pipe2() +{ +/* Perform the pipe2(fil_des[2], flags) system call. */ + int r, flags; + int fil_des[2]; /* reply goes here */ + + flags = job_m_in.pipe_flags; + + r = create_pipe(fil_des, flags); + if (r == OK) { + m_out.reply_i1 = fil_des[0]; + m_out.reply_i2 = fil_des[1]; + } + + return r; +} + +/*===========================================================================* + * create_pipe * + *===========================================================================*/ +static int create_pipe(int fil_des[2], int flags) +{ register struct fproc *rfp; int r; struct filp *fil_ptr0, *fil_ptr1; - int fil_des[2]; /* reply goes here */ struct vnode *vp; struct vmnt *vmp; struct node_details res; @@ -119,11 +156,12 @@ int do_pipe() fil_ptr0->filp_vno = vp; dup_vnode(vp); fil_ptr1->filp_vno = vp; - fil_ptr0->filp_flags = O_RDONLY; - fil_ptr1->filp_flags = O_WRONLY; - - m_out.reply_i1 = fil_des[0]; - m_out.reply_i2 = fil_des[1]; + fil_ptr0->filp_flags = O_RDONLY | (flags & ~O_ACCMODE); + fil_ptr1->filp_flags = O_WRONLY | (flags & ~O_ACCMODE); + if (flags & O_CLOEXEC) { + FD_SET(fil_des[0], &rfp->fp_cloexec_set); + FD_SET(fil_des[1], &rfp->fp_cloexec_set); + } unlock_filps(fil_ptr0, fil_ptr1); unlock_vmnt(vmp); diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 48865d6cb..82a7aecd8 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -184,6 +184,7 @@ int do_check_perms(void); /* pipe.c */ int do_pipe(void); +int do_pipe2(void); int map_vnode(struct vnode *vp, endpoint_t fs_e); void unpause(endpoint_t proc_e); int pipe_check(struct filp *filp, int rw_flag, int oflags, int bytes, diff --git a/servers/vfs/table.c b/servers/vfs/table.c index 8371e3498..808a4abd4 100644 --- a/servers/vfs/table.c +++ b/servers/vfs/table.c @@ -73,7 +73,7 @@ int (*call_vec[])(void) = { do_fcntl, /* 55 = fcntl */ no_sys, /* 56 = (mpx) */ do_fsready, /* 57 = FS proc ready */ - no_sys, /* 58 = unused */ + do_pipe2, /* 58 = pipe2 */ no_sys, /* 59 = (execve)*/ do_umask, /* 60 = umask */ do_chroot, /* 61 = chroot */