svn commit: r255299 - stable/9/sys/kern
Jilles Tjoelker
jilles at FreeBSD.org
Fri Sep 6 12:45:09 UTC 2013
Author: jilles
Date: Fri Sep 6 12:45:08 2013
New Revision: 255299
URL: http://svnweb.freebsd.org/changeset/base/255299
Log:
Partial MFC of r248534: Implement SOCK_CLOEXEC and SOCK_NONBLOCK in kernel.
SOCK_CLOEXEC and SOCK_NONBLOCK can be OR'ed in socket() and socketpair()'s
type parameter.
The numerical values for SOCK_CLOEXEC and SOCK_NONBLOCK are as in NetBSD.
The SOCK_* flags are not passed to MAC because this may cause incorrect
failures and can be done later via fcntl() anyway. On the other hand, audit
is expected to cope with the new flags.
This commit does not add the constants to <sys/socket.h> as in r248534
because this would lead to various newly compiled software not working on
old kernels. It only serves to help 10.x binaries and prepare for a possible
full MFC (if third-party software starts to insist on SOCK_CLOEXEC and
SOCK_NONBLOCK).
MSG_CMSG_CLOEXEC from r248534 is not merged here because it changes a
KPI/KBI.
No mergeinfo because the rest of r248534 is missing.
Modified:
stable/9/sys/kern/uipc_syscalls.c
Modified: stable/9/sys/kern/uipc_syscalls.c
==============================================================================
--- stable/9/sys/kern/uipc_syscalls.c Fri Sep 6 10:40:38 2013 (r255298)
+++ stable/9/sys/kern/uipc_syscalls.c Fri Sep 6 12:45:08 2013 (r255299)
@@ -96,6 +96,13 @@ __FBSDID("$FreeBSD$");
#endif /* SCTP */
#endif /* INET || INET6 */
+/*
+ * Creation flags, OR'ed into socket() and socketpair() type argument.
+ * For stable/9, these are supported but not exposed in the header file.
+ */
+#define SOCK_CLOEXEC 0x10000000
+#define SOCK_NONBLOCK 0x20000000
+
static int sendit(struct thread *td, int s, struct msghdr *mp, int flags);
static int recvit(struct thread *td, int s, struct msghdr *mp, void *namelenp);
@@ -183,26 +190,41 @@ sys_socket(td, uap)
struct filedesc *fdp;
struct socket *so;
struct file *fp;
- int fd, error;
+ int fd, error, type, oflag, fflag;
AUDIT_ARG_SOCKET(uap->domain, uap->type, uap->protocol);
+
+ type = uap->type;
+ oflag = 0;
+ fflag = 0;
+ if ((type & SOCK_CLOEXEC) != 0) {
+ type &= ~SOCK_CLOEXEC;
+ oflag |= O_CLOEXEC;
+ }
+ if ((type & SOCK_NONBLOCK) != 0) {
+ type &= ~SOCK_NONBLOCK;
+ fflag |= FNONBLOCK;
+ }
+
#ifdef MAC
- error = mac_socket_check_create(td->td_ucred, uap->domain, uap->type,
+ error = mac_socket_check_create(td->td_ucred, uap->domain, type,
uap->protocol);
if (error)
return (error);
#endif
fdp = td->td_proc->p_fd;
- error = falloc(td, &fp, &fd, 0);
+ error = falloc(td, &fp, &fd, oflag);
if (error)
return (error);
/* An extra reference on `fp' has been held for us by falloc(). */
- error = socreate(uap->domain, &so, uap->type, uap->protocol,
+ error = socreate(uap->domain, &so, type, uap->protocol,
td->td_ucred, td);
if (error) {
fdclose(fdp, fp, fd, td);
} else {
- finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops);
+ finit(fp, FREAD | FWRITE | fflag, DTYPE_SOCKET, so, &socketops);
+ if ((fflag & FNONBLOCK) != 0)
+ (void) fo_ioctl(fp, FIONBIO, &fflag, td->td_ucred, td);
td->td_retval[0] = fd;
}
fdrop(fp, td);
@@ -606,9 +628,20 @@ kern_socketpair(struct thread *td, int d
struct filedesc *fdp = td->td_proc->p_fd;
struct file *fp1, *fp2;
struct socket *so1, *so2;
- int fd, error;
+ int fd, error, oflag, fflag;
AUDIT_ARG_SOCKET(domain, type, protocol);
+
+ oflag = 0;
+ fflag = 0;
+ if ((type & SOCK_CLOEXEC) != 0) {
+ type &= ~SOCK_CLOEXEC;
+ oflag |= O_CLOEXEC;
+ }
+ if ((type & SOCK_NONBLOCK) != 0) {
+ type &= ~SOCK_NONBLOCK;
+ fflag |= FNONBLOCK;
+ }
#ifdef MAC
/* We might want to have a separate check for socket pairs. */
error = mac_socket_check_create(td->td_ucred, domain, type,
@@ -623,12 +656,12 @@ kern_socketpair(struct thread *td, int d
if (error)
goto free1;
/* On success extra reference to `fp1' and 'fp2' is set by falloc. */
- error = falloc(td, &fp1, &fd, 0);
+ error = falloc(td, &fp1, &fd, oflag);
if (error)
goto free2;
rsv[0] = fd;
fp1->f_data = so1; /* so1 already has ref count */
- error = falloc(td, &fp2, &fd, 0);
+ error = falloc(td, &fp2, &fd, oflag);
if (error)
goto free3;
fp2->f_data = so2; /* so2 already has ref count */
@@ -644,8 +677,14 @@ kern_socketpair(struct thread *td, int d
if (error)
goto free4;
}
- finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops);
- finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops);
+ finit(fp1, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp1->f_data,
+ &socketops);
+ finit(fp2, FREAD | FWRITE | fflag, DTYPE_SOCKET, fp2->f_data,
+ &socketops);
+ if ((fflag & FNONBLOCK) != 0) {
+ (void) fo_ioctl(fp1, FIONBIO, &fflag, td->td_ucred, td);
+ (void) fo_ioctl(fp2, FIONBIO, &fflag, td->td_ucred, td);
+ }
fdrop(fp1, td);
fdrop(fp2, td);
return (0);
More information about the svn-src-stable-9
mailing list