diff options
-rw-r--r-- | usr/src/man/man3socket/socket.3socket | 31 | ||||
-rw-r--r-- | usr/src/uts/common/fs/sockfs/socksyscalls.c | 26 |
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); } |