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
This commit is contained in:
jilles 2013-05-01 22:42:42 +00:00
parent a7b320131e
commit 16772c421d
8 changed files with 68 additions and 2 deletions

View File

@ -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 *,

View File

@ -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

View File

@ -393,6 +393,7 @@ FBSD_1.3 {
ffclock_getcounter;
ffclock_getestimate;
ffclock_setestimate;
pipe2;
posix_fadvise;
wait6;
};

View File

@ -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 .

View File

@ -1026,3 +1026,4 @@
struct sockaddr * __restrict name, \
__socklen_t * __restrict anamelen, \
int flags); }
542 AUE_PIPE NOPROTO { int pipe2(int *fildes, int flags); }

View File

@ -490,6 +490,7 @@ pdkill
## Allow pipe(2).
##
pipe
pipe2
##
## Allow poll(2), which will be scoped by capability rights.

View File

@ -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

View File

@ -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