1 #include <sys/cdefs.h> 2 #include "namespace.h" 3 #include <lib.h> 4 5 #include <string.h> 6 #include <errno.h> 7 #include <stdio.h> 8 #include <sys/ioctl.h> 9 #include <sys/socket.h> 10 #include <sys/un.h> 11 12 #include <net/gen/in.h> 13 #include <net/gen/tcp.h> 14 #include <net/gen/tcp_io.h> 15 16 #define DEBUG 0 17 18 static int _tcp_shutdown(int sock, int how); 19 static int _uds_shutdown(int sock, int how); 20 21 /* 22 * Shut down socket send and receive operations. 23 */ 24 static int 25 __shutdown(int fd, int how) 26 { 27 message m; 28 29 memset(&m, 0, sizeof(m)); 30 m.m_lc_vfs_shutdown.fd = fd; 31 m.m_lc_vfs_shutdown.how = how; 32 33 return _syscall(VFS_PROC_NR, VFS_SHUTDOWN, &m); 34 } 35 36 int shutdown(int sock, int how) 37 { 38 int r; 39 struct sockaddr_un uds_addr; 40 nwio_tcpconf_t tcpconf; 41 42 r = __shutdown(sock, how); 43 if (r != -1 || (errno != ENOTSOCK && errno != ENOSYS)) 44 return r; 45 46 r= ioctl(sock, NWIOGTCPCONF, &tcpconf); 47 if (r != -1 || errno != ENOTTY) 48 { 49 if (r == -1) 50 { 51 /* Bad file descriptor */ 52 return -1; 53 } 54 return _tcp_shutdown(sock, how); 55 } 56 57 r= ioctl(sock, NWIOGUDSADDR, &uds_addr); 58 if (r != -1 || errno != ENOTTY) 59 { 60 if (r == -1) 61 { 62 /* Bad file descriptor */ 63 return -1; 64 } 65 return _uds_shutdown(sock, how); 66 } 67 68 errno = ENOTSOCK; 69 return -1; 70 } 71 72 static int _tcp_shutdown(int sock, int how) 73 { 74 int r; 75 76 if (how == SHUT_WR || how == SHUT_RDWR) 77 { 78 r= ioctl(sock, NWIOTCPSHUTDOWN, NULL); 79 if (r == -1) 80 return -1; 81 if (how == SHUT_WR) 82 return 0; 83 } 84 85 /* We can't shutdown the read side of the socket. */ 86 errno= ENOSYS; 87 return -1; 88 } 89 90 static int _uds_shutdown(int sock, int how) 91 { 92 return ioctl(sock, NWIOSUDSSHUT, &how); 93 } 94