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 55a146bac..878ebe2f0 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/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/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 4a61e7e75..a7cce2f66 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,8 @@ 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); unlock_filps(fil_ptr0, fil_ptr1); unlock_vmnt(vmp); diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index b98d7420d..b500c8f4d 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 vnode *vp, 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 */