summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/man/man3socket/socket.3socket31
-rw-r--r--usr/src/uts/common/fs/sockfs/socksyscalls.c26
2 files changed, 56 insertions, 1 deletions
diff --git a/usr/src/man/man3socket/socket.3socket b/usr/src/man/man3socket/socket.3socket
index be280b082e..74c2acbc06 100644
--- a/usr/src/man/man3socket/socket.3socket
+++ b/usr/src/man/man3socket/socket.3socket
@@ -100,6 +100,28 @@ is similar in purpose to the \fBO_CLOEXEC\fR flag to \fBopen\fR(2).
.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 protocol type is not supported by the address family.
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
diff --git a/usr/src/uts/common/fs/sockfs/socksyscalls.c b/usr/src/uts/common/fs/sockfs/socksyscalls.c
index 078b32fa76..4ec7eee2ca 100644
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c
@@ -109,6 +109,10 @@ so_socket(int family, int type_w_flags, int protocol, char *devpath,
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 @@ so_socket(int family, int type_w_flags, int protocol, char *devpath,
/*
* 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 @@ so_socketpair(int sv[2])
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 @@ so_socketpair(int sv[2])
* 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);
}