changeset 14028:d685c72a19b6

3769 Implement SOCK_NONBLOCK flag to socket() Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Theo Schlossnagle <jesus@omniti.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Keith M Wesolowski <wesolows@foobazco.org>
date Mon, 13 May 2013 17:47:27 +0000
parents be5763401f27
children 2031dcee618b
files usr/src/man/man3socket/socket.3socket usr/src/uts/common/fs/sockfs/socksyscalls.c
diffstat 2 files changed, 56 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/man/man3socket/socket.3socket	Fri May 03 15:32:31 2013 +0200
+++ b/usr/src/man/man3socket/socket.3socket	Mon May 13 17:47:27 2013 +0000
@@ -100,6 +100,28 @@
 .RE
 
 .sp
+.ne 2
+.na
+\fB\fBSOCK_NDELAY\fR\fR
+.ad
+.RS 12n
+Creates the socket with the \fBO_NDELAY\fR flag set, causing the socket to
+provide nonblocking semantics as described for \fBO_NDELAY\fR in \fBopen\fR(2).
+\fBSOCK_NONBLOCK\fR should normally be used in preference to \fBSOCK_NDELAY\fR,
+and takes precedence if both are set.  See \fBopen\fR(2) for further details.
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fBSOCK_NONBLOCK\fR\fR
+.ad
+.RS 12n
+Creates the socket with the \fBO_NONBLOCK\fR flag set, causing the socket to
+provide nonblocking semantics as described for \fBO_NONBLOCK\fR in \fBopen\fR(2).
+.RE
+
+.sp
 .LP
 There must be an entry in the \fBnetconfig\fR(4) file for at least each
 protocol family and type required. If  a non-zero protocol has been specified
@@ -264,6 +286,15 @@
 The socket type is not supported by the protocol.
 .RE
 
+.sp
+.ne 2
+.na
+\fB\fBEINVAL\fR\fR
+.ad
+.RS 19n
+One or more of the specified flags is not supported.
+.RE
+
 .SH ATTRIBUTES
 .sp
 .LP
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c	Fri May 03 15:32:31 2013 +0200
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c	Mon May 13 17:47:27 2013 +0000
@@ -109,6 +109,10 @@
 	int type;
 
 	type = type_w_flags & SOCK_TYPE_MASK;
+	type_w_flags &= ~SOCK_TYPE_MASK;
+	if (type_w_flags & ~(SOCK_CLOEXEC|SOCK_NDELAY|SOCK_NONBLOCK))
+		return (set_errno(EINVAL));
+
 	if (devpath != NULL) {
 		char *buf;
 		size_t kdevpathlen = 0;
@@ -140,6 +144,14 @@
 	/*
 	 * Now fill in the entries that falloc reserved
 	 */
+	if (type_w_flags & SOCK_NDELAY) {
+		so->so_state |= SS_NDELAY;
+		fp->f_flag |= FNDELAY;
+	}
+	if (type_w_flags & SOCK_NONBLOCK) {
+		so->so_state |= SS_NONBLOCK;
+		fp->f_flag |= FNONBLOCK;
+	}
 	mutex_exit(&fp->f_tlock);
 	setf(fd, fp);
 	if ((type_w_flags & SOCK_CLOEXEC) != 0) {
@@ -488,11 +500,24 @@
 			goto done;
 		}
 		/*
+		 * copy over FNONBLOCK and FNDELAY flags should they exist
+		 */
+		if (so1->so_state & SS_NONBLOCK)
+			nfp->f_flag |= FNONBLOCK;
+		if (so1->so_state & SS_NDELAY)
+			nfp->f_flag |= FNDELAY;
+
+		/*
 		 * fill in the entries that falloc reserved
 		 */
 		mutex_exit(&nfp->f_tlock);
 		setf(nfd, nfp);
 
+		/*
+		 * get the original flags before we release
+		 */
+		VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
+
 		releasef(svs[0]);
 		releasef(svs[1]);
 
@@ -500,7 +525,6 @@
 		 * If FD_CLOEXEC was set on the filedescriptor we're
 		 * swapping out, we should set it on the new one too.
 		 */
-		VERIFY(f_getfd_error(svs[0], &orig_flags) == 0);
 		if (orig_flags & FD_CLOEXEC) {
 			f_setfd(nfd, FD_CLOEXEC);
 		}