1433d6423SLionel Sambuc #include <sys/cdefs.h> 2433d6423SLionel Sambuc #include "namespace.h" 3*c38dbb97SDavid van Moolenbroek #include <lib.h> 4433d6423SLionel Sambuc 5*c38dbb97SDavid van Moolenbroek #include <string.h> 6433d6423SLionel Sambuc #include <errno.h> 7433d6423SLionel Sambuc #include <stdio.h> 8433d6423SLionel Sambuc #include <sys/ioctl.h> 9433d6423SLionel Sambuc #include <sys/socket.h> 10433d6423SLionel Sambuc #include <sys/un.h> 11433d6423SLionel Sambuc 12433d6423SLionel Sambuc #include <net/gen/in.h> 13433d6423SLionel Sambuc #include <net/gen/tcp.h> 14433d6423SLionel Sambuc #include <net/gen/tcp_io.h> 15433d6423SLionel Sambuc 16433d6423SLionel Sambuc #define DEBUG 0 17433d6423SLionel Sambuc 18433d6423SLionel Sambuc static int _tcp_shutdown(int sock, int how); 19433d6423SLionel Sambuc static int _uds_shutdown(int sock, int how); 20433d6423SLionel Sambuc 21*c38dbb97SDavid van Moolenbroek /* 22*c38dbb97SDavid van Moolenbroek * Shut down socket send and receive operations. 23*c38dbb97SDavid van Moolenbroek */ 24*c38dbb97SDavid van Moolenbroek static int 25*c38dbb97SDavid van Moolenbroek __shutdown(int fd, int how) 26*c38dbb97SDavid van Moolenbroek { 27*c38dbb97SDavid van Moolenbroek message m; 28*c38dbb97SDavid van Moolenbroek 29*c38dbb97SDavid van Moolenbroek memset(&m, 0, sizeof(m)); 30*c38dbb97SDavid van Moolenbroek m.m_lc_vfs_shutdown.fd = fd; 31*c38dbb97SDavid van Moolenbroek m.m_lc_vfs_shutdown.how = how; 32*c38dbb97SDavid van Moolenbroek 33*c38dbb97SDavid van Moolenbroek return _syscall(VFS_PROC_NR, VFS_SHUTDOWN, &m); 34*c38dbb97SDavid van Moolenbroek } 35*c38dbb97SDavid van Moolenbroek 36433d6423SLionel Sambuc int shutdown(int sock, int how) 37433d6423SLionel Sambuc { 38433d6423SLionel Sambuc int r; 39433d6423SLionel Sambuc struct sockaddr_un uds_addr; 40433d6423SLionel Sambuc nwio_tcpconf_t tcpconf; 41433d6423SLionel Sambuc 42*c38dbb97SDavid van Moolenbroek r = __shutdown(sock, how); 43*c38dbb97SDavid van Moolenbroek if (r != -1 || errno != ENOTSOCK) 44*c38dbb97SDavid van Moolenbroek return r; 45*c38dbb97SDavid van Moolenbroek 46433d6423SLionel Sambuc r= ioctl(sock, NWIOGTCPCONF, &tcpconf); 47433d6423SLionel Sambuc if (r != -1 || errno != ENOTTY) 48433d6423SLionel Sambuc { 49433d6423SLionel Sambuc if (r == -1) 50433d6423SLionel Sambuc { 51433d6423SLionel Sambuc /* Bad file descriptor */ 52433d6423SLionel Sambuc return -1; 53433d6423SLionel Sambuc } 54433d6423SLionel Sambuc return _tcp_shutdown(sock, how); 55433d6423SLionel Sambuc } 56433d6423SLionel Sambuc 57433d6423SLionel Sambuc r= ioctl(sock, NWIOGUDSADDR, &uds_addr); 58433d6423SLionel Sambuc if (r != -1 || errno != ENOTTY) 59433d6423SLionel Sambuc { 60433d6423SLionel Sambuc if (r == -1) 61433d6423SLionel Sambuc { 62433d6423SLionel Sambuc /* Bad file descriptor */ 63433d6423SLionel Sambuc return -1; 64433d6423SLionel Sambuc } 65433d6423SLionel Sambuc return _uds_shutdown(sock, how); 66433d6423SLionel Sambuc } 67433d6423SLionel Sambuc 68*c38dbb97SDavid van Moolenbroek errno = ENOTSOCK; 69433d6423SLionel Sambuc return -1; 70433d6423SLionel Sambuc } 71433d6423SLionel Sambuc 72433d6423SLionel Sambuc static int _tcp_shutdown(int sock, int how) 73433d6423SLionel Sambuc { 74433d6423SLionel Sambuc int r; 75433d6423SLionel Sambuc 76433d6423SLionel Sambuc if (how == SHUT_WR || how == SHUT_RDWR) 77433d6423SLionel Sambuc { 78433d6423SLionel Sambuc r= ioctl(sock, NWIOTCPSHUTDOWN, NULL); 79433d6423SLionel Sambuc if (r == -1) 80433d6423SLionel Sambuc return -1; 81433d6423SLionel Sambuc if (how == SHUT_WR) 82433d6423SLionel Sambuc return 0; 83433d6423SLionel Sambuc } 84433d6423SLionel Sambuc 85433d6423SLionel Sambuc /* We can't shutdown the read side of the socket. */ 86433d6423SLionel Sambuc errno= ENOSYS; 87433d6423SLionel Sambuc return -1; 88433d6423SLionel Sambuc } 89433d6423SLionel Sambuc 90433d6423SLionel Sambuc static int _uds_shutdown(int sock, int how) 91433d6423SLionel Sambuc { 92433d6423SLionel Sambuc return ioctl(sock, NWIOSUDSSHUT, &how); 93433d6423SLionel Sambuc } 94