Index: sys/kern/uipc_socket.c =================================================================== --- sys/kern/uipc_socket.c +++ sys/kern/uipc_socket.c @@ -2334,6 +2334,9 @@ 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) Index: sys/kern/uipc_syscalls.c =================================================================== --- sys/kern/uipc_syscalls.c +++ sys/kern/uipc_syscalls.c @@ -1383,6 +1383,15 @@ 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); Index: sys/sys/param.h =================================================================== --- sys/sys/param.h +++ 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