VFS: implement pipe2
Change-Id: Iedc8042dd73a903456b25ba665d12577f5589ca2
This commit is contained in:
parent
fa78dc389f
commit
473547c777
14 changed files with 91 additions and 110 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 <unistd.h>
|
||||
|
||||
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.
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue