xref: /minix/minix/lib/libc/sys/shutdown.c (revision fb9c64b2)
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