libutil: add O_NOCTTY back to old pty open code
[minix.git] / lib / libc / sys-minix / accept.c
blob88c9c9c0ce08cbcfc9a9ec0eb618ca9a2451960d
1 #include <sys/cdefs.h>
2 #include "namespace.h"
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <string.h>
10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 #include <sys/un.h>
14 #include <net/netlib.h>
15 #include <net/gen/in.h>
16 #include <net/gen/tcp.h>
17 #include <net/gen/tcp_io.h>
18 #include <net/gen/udp.h>
19 #include <net/gen/udp_io.h>
21 #define DEBUG 0
23 static int _tcp_accept(int sock, struct sockaddr *__restrict address,
24 socklen_t *__restrict address_len);
26 static int _uds_accept(int sock, struct sockaddr *__restrict address,
27 socklen_t *__restrict address_len);
29 int accept(int sock, struct sockaddr *__restrict address,
30 socklen_t *__restrict address_len)
32 int r;
33 nwio_udpopt_t udpopt;
35 r= _tcp_accept(sock, address, address_len);
36 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
37 return r;
39 r= _uds_accept(sock, address, address_len);
40 if (r != -1 || (errno != ENOTTY && errno != EBADIOCTL))
41 return r;
43 /* Unfortunately, we have to return EOPNOTSUPP for a socket that
44 * does not support accept (such as a UDP socket) and ENOTSOCK for
45 * filedescriptors that do not refer to a socket.
47 r= ioctl(sock, NWIOGUDPOPT, &udpopt);
48 if (r == 0)
50 /* UDP socket */
51 errno= EOPNOTSUPP;
52 return -1;
54 if ((errno == ENOTTY || errno == EBADIOCTL))
56 errno= ENOTSOCK;
57 return -1;
60 return r;
63 static int _tcp_accept(int sock, struct sockaddr *__restrict address,
64 socklen_t *__restrict address_len)
66 int r, s1, t_errno;
67 tcp_cookie_t cookie;
69 s1= open(TCP_DEVICE, O_RDWR);
70 if (s1 == -1)
71 return s1;
72 r= ioctl(s1, NWIOGTCPCOOKIE, &cookie);
73 if (r == -1)
75 t_errno= errno;
76 close(s1);
77 errno= t_errno;
78 return -1;
80 r= ioctl(sock, NWIOTCPACCEPTTO, &cookie);
81 if (r == -1)
83 t_errno= errno;
84 close(s1);
85 errno= t_errno;
86 return -1;
88 if (address != NULL)
89 getpeername(s1, address, address_len);
90 return s1;
93 static int _uds_accept(int sock, struct sockaddr *__restrict address,
94 socklen_t *__restrict address_len)
96 int s1;
97 int r;
98 struct sockaddr_un uds_addr;
99 socklen_t len;
101 memset(&uds_addr, '\0', sizeof(struct sockaddr_un));
103 r= ioctl(sock, NWIOGUDSADDR, &uds_addr);
104 if (r == -1) {
105 return r;
108 if (uds_addr.sun_family != AF_UNIX) {
109 errno= EINVAL;
110 return -1;
113 len= *address_len;
114 if (len > sizeof(struct sockaddr_un))
115 len = sizeof(struct sockaddr_un);
117 memcpy(address, &uds_addr, len);
118 *address_len= len;
120 s1= open(UDS_DEVICE, O_RDWR);
121 if (s1 == -1)
122 return s1;
124 r= ioctl(s1, NWIOSUDSACCEPT, address);
125 if (r == -1) {
126 int ioctl_errno = errno;
127 close(s1);
128 errno = ioctl_errno;
129 return r;
132 return s1;