summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2013-05-01 22:42:42 +0000
committerjilles <jilles@FreeBSD.org>2013-05-01 22:42:42 +0000
commit16772c421df1aaea1f268ea43b53e1b21a40be99 (patch)
tree69471087fd1663f8e867f7e487ae78525a10941b
parenta7b320131e8beb106b450826aa74a2797328cd8b (diff)
downloadFreeBSD-src-16772c421df1aaea1f268ea43b53e1b21a40be99.zip
FreeBSD-src-16772c421df1aaea1f268ea43b53e1b21a40be99.tar.gz
Add pipe2() system call.
The pipe2() function is similar to pipe() but allows setting FD_CLOEXEC and O_NONBLOCK (on both sides) as part of the function. If p points to two writable ints, pipe2(p, 0) is equivalent to pipe(p). If the pointer is not valid, behaviour differs: pipe2() writes into the array from the kernel like socketpair() does, while pipe() writes into the array from an architecture-specific assembler wrapper. Reviewed by: kan, kib
-rw-r--r--include/unistd.h1
-rw-r--r--lib/libc/sys/Makefile.inc1
-rw-r--r--lib/libc/sys/Symbol.map1
-rw-r--r--lib/libc/sys/pipe.246
-rw-r--r--sys/compat/freebsd32/syscalls.master1
-rw-r--r--sys/kern/capabilities.conf1
-rw-r--r--sys/kern/sys_pipe.c18
-rw-r--r--sys/kern/syscalls.master1
8 files changed, 68 insertions, 2 deletions
diff --git a/include/unistd.h b/include/unistd.h
index dabf178..9df0777 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -533,6 +533,7 @@ char *mktemp(char *);
#endif
int nfssvc(int, void *);
int nlm_syscall(int, int, int, char **);
+int pipe2(int *, int);
int profil(char *, size_t, vm_offset_t, int);
int rcmd(char **, int, const char *, const char *, const char *, int *);
int rcmd_af(char **, int, const char *,
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 105f469..8e918bf 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -352,6 +352,7 @@ MLINKS+=pathconf.2 lpathconf.2
MLINKS+=pdfork.2 pdgetpid.2\
pdfork.2 pdkill.2 \
pdfork.2 pdwait4.2
+MLINKS+=pipe.2 pipe2.2
MLINKS+=read.2 pread.2 \
read.2 preadv.2 \
read.2 readv.2
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index 149fa41..24f4621 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -393,6 +393,7 @@ FBSD_1.3 {
ffclock_getcounter;
ffclock_getestimate;
ffclock_setestimate;
+ pipe2;
posix_fadvise;
wait6;
};
diff --git a/lib/libc/sys/pipe.2 b/lib/libc/sys/pipe.2
index 92d137f..bb3db51 100644
--- a/lib/libc/sys/pipe.2
+++ b/lib/libc/sys/pipe.2
@@ -28,7 +28,7 @@
.\" @(#)pipe.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd January 30, 2006
+.Dd March 31, 2013
.Dt PIPE 2
.Os
.Sh NAME
@@ -40,6 +40,8 @@
.In unistd.h
.Ft int
.Fn pipe "int fildes[2]"
+.Ft int
+.Fn pipe2 "int fildes[2]" "int flags"
.Sh DESCRIPTION
The
.Fn pipe
@@ -50,6 +52,29 @@ which is an object allowing
bidirectional data flow,
and allocates a pair of file descriptors.
.Pp
+The
+.Fn pipe2
+system call allows control over the attributes of the file descriptors
+via the
+.Fa flags
+argument.
+Values for
+.Fa flags
+are constructed by a bitwise-inclusive OR of flags from the following
+list, defined in
+.In fcntl.h :
+.Bl -tag -width ".Dv O_NONBLOCK"
+.It Dv O_CLOEXEC
+Set the close-on-exec flag for the new file descriptors.
+.It Dv O_NONBLOCK
+Set the non-blocking flag for the ends of the pipe.
+.El
+.Pp
+If the
+.Fa flags
+argument is 0, the behavior is identical to a call to
+.Fn pipe .
+.Pp
By convention, the first descriptor is normally used as the
.Em read end
of the pipe,
@@ -88,7 +113,9 @@ pipe in one direction.
.Sh ERRORS
The
.Fn pipe
-system call will fail if:
+and
+.Fn pipe2
+system calls will fail if:
.Bl -tag -width Er
.It Bq Er EMFILE
Too many descriptors are active.
@@ -97,6 +124,16 @@ The system file table is full.
.It Bq Er ENOMEM
Not enough kernel memory to establish a pipe.
.El
+.Pp
+The
+.Fn pipe2
+system call will also fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa flags
+argument is invalid.
+.El
.Sh SEE ALSO
.Xr sh 1 ,
.Xr fork 2 ,
@@ -111,3 +148,8 @@ function appeared in
.Pp
Bidirectional pipes were first used on
.At V.4 .
+.Pp
+The
+.Fn pipe2
+function appeared in
+.Fx 10.0 .
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 2cbdf31..be245be 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -1026,3 +1026,4 @@
struct sockaddr * __restrict name, \
__socklen_t * __restrict anamelen, \
int flags); }
+542 AUE_PIPE NOPROTO { int pipe2(int *fildes, int flags); }
diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf
index 0b64503..d2fa51c 100644
--- a/sys/kern/capabilities.conf
+++ b/sys/kern/capabilities.conf
@@ -490,6 +490,7 @@ pdkill
## Allow pipe(2).
##
pipe
+pipe2
##
## Allow poll(2), which will be scoped by capability rights.
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 90c3022..493fee5e 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -477,6 +477,24 @@ sys_pipe(struct thread *td, struct pipe_args *uap)
return (0);
}
+int
+sys_pipe2(struct thread *td, struct pipe2_args *uap)
+{
+ int error, fildes[2];
+
+ if (uap->flags & ~(O_CLOEXEC | O_NONBLOCK))
+ return (EINVAL);
+ error = kern_pipe2(td, fildes, uap->flags);
+ if (error)
+ return (error);
+ error = copyout(fildes, uap->fildes, 2 * sizeof(int));
+ if (error) {
+ (void)kern_close(td, fildes[0]);
+ (void)kern_close(td, fildes[1]);
+ }
+ return (error);
+}
+
/*
* Allocate kva for pipe circular buffer, the space is pageable
* This routine will 'realloc' the size of a pipe safely, if it fails
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 922db30..8668943 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -976,5 +976,6 @@
struct sockaddr * __restrict name, \
__socklen_t * __restrict anamelen, \
int flags); }
+542 AUE_PIPE STD { int pipe2(int *fildes, int flags); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
OpenPOWER on IntegriCloud