summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/shutdown.242
-rw-r--r--sys/kern/uipc_socket.c3
-rw-r--r--sys/kern/uipc_syscalls.c9
-rw-r--r--sys/sys/param.h11
4 files changed, 29 insertions, 36 deletions
diff --git a/lib/libc/sys/shutdown.2 b/lib/libc/sys/shutdown.2
index e8a434b..35c464e 100644
--- a/lib/libc/sys/shutdown.2
+++ b/lib/libc/sys/shutdown.2
@@ -29,7 +29,7 @@
.\" @(#)shutdown.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd March 5, 2007
+.Dd July 27, 2015
.Dt SHUTDOWN 2
.Os
.Sh NAME
@@ -79,40 +79,26 @@ The following protocol specific actions apply to the use of
based on the properties of the socket associated with the file descriptor
.Fa s .
.Bl -column ".Dv PF_INET6" ".Dv SOCK_STREAM" ".Dv IPPROTO_SCTP"
-.It Sy Domain Ta Sy Type Ta Sy Protocol Ta Sy Return value and action
+.It Sy Domain Ta Sy Type Ta Sy Protocol Ta Sy Action
.It Dv PF_INET Ta Dv SOCK_DGRAM Ta Dv IPPROTO_SCTP Ta
-Return \-1.
-The global variable
-.Va errno
-will be set to
-.Er EOPNOTSUPP .
+Failure,
+as socket is not connected.
.It Dv PF_INET Ta Dv SOCK_DGRAM Ta Dv IPPROTO_UDP Ta
-Return 0.
-ICMP messages will
-.Em not
-be generated.
+Failure,
+as socket is not connected.
.It Dv PF_INET Ta Dv SOCK_STREAM Ta Dv IPPROTO_SCTP Ta
-Return 0.
Send queued data and tear down association.
.It Dv PF_INET Ta Dv SOCK_STREAM Ta Dv IPPROTO_TCP Ta
-Return 0.
Send queued data, wait for ACK, then send FIN.
.It Dv PF_INET6 Ta Dv SOCK_DGRAM Ta Dv IPPROTO_SCTP Ta
-Return \-1.
-The global variable
-.Va errno
-will be set to
-.Er EOPNOTSUPP .
+Failure,
+as socket is not connected.
.It Dv PF_INET6 Ta Dv SOCK_DGRAM Ta Dv IPPROTO_UDP Ta
-Return 0.
-ICMP messages will
-.Em not
-be generated.
+Failure,
+as socket is not connected.
.It Dv PF_INET6 Ta Dv SOCK_STREAM Ta Dv IPPROTO_SCTP Ta
-Return 0.
Send queued data and tear down association.
.It Dv PF_INET6 Ta Dv SOCK_STREAM Ta Dv IPPROTO_TCP Ta
-Return 0.
Send queued data, wait for ACK, then send FIN.
.El
.\"
@@ -131,16 +117,10 @@ argument is not a valid file descriptor.
The
.Fa how
argument is invalid.
-.It Bq Er EOPNOTSUPP
-The socket associated with the file descriptor
-.Fa s
-does not support this operation.
.It Bq Er ENOTCONN
The
.Fa s
-argument specifies a
-.Dv SOCK_STREAM
-socket which is not connected.
+argument specifies a socket which is not connected.
.It Bq Er ENOTSOCK
The
.Fa s
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 58a38f2..350ca3c 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -2334,6 +2334,9 @@ soshutdown(struct socket *so, int how)
if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
return (EINVAL);
+ if ((so->so_state &
+ (SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0)
+ return (ENOTCONN);
CURVNET_SET(so->so_vnet);
if (pr->pr_usrreqs->pru_flush != NULL)
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e3557ba..54c13024 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1383,6 +1383,15 @@ sys_shutdown(td, uap)
if (error == 0) {
so = fp->f_data;
error = soshutdown(so, uap->how);
+ /*
+ * Previous versions did not return ENOTCONN, but 0 in
+ * case the socket was not connected. Some important
+ * programs like syslogd up to r279016, 2015-02-19,
+ * still depend on this behavior.
+ */
+ if (error == ENOTCONN &&
+ td->td_proc->p_osrel < P_OSREL_SHUTDOWN_ENOTCONN)
+ error = 0;
fdrop(fp, td);
}
return (error);
diff --git a/sys/sys/param.h b/sys/sys/param.h
index a146da8..5f66656 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -77,12 +77,13 @@
#define __FreeBSD_kernel__
#ifdef _KERNEL
-#define P_OSREL_SIGWAIT 700000
-#define P_OSREL_SIGSEGV 700004
-#define P_OSREL_MAP_ANON 800104
-#define P_OSREL_MAP_FSTRICT 1100036
+#define P_OSREL_SIGWAIT 700000
+#define P_OSREL_SIGSEGV 700004
+#define P_OSREL_MAP_ANON 800104
+#define P_OSREL_MAP_FSTRICT 1100036
+#define P_OSREL_SHUTDOWN_ENOTCONN 1100077
-#define P_OSREL_MAJOR(x) ((x) / 100000)
+#define P_OSREL_MAJOR(x) ((x) / 100000)
#endif
#ifndef LOCORE
OpenPOWER on IntegriCloud