10 #include <sys/ioctl.h>
11 #include <sys/socket.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>
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
)
35 r
= _tcp_accept(sock
, address
, address_len
);
36 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
39 r
= _uds_accept(sock
, address
, address_len
);
40 if (r
!= -1 || (errno
!= ENOTTY
&& errno
!= EBADIOCTL
))
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
);
54 if ((errno
== ENOTTY
|| errno
== EBADIOCTL
))
63 static int _tcp_accept(int sock
, struct sockaddr
*__restrict address
,
64 socklen_t
*__restrict address_len
)
69 s1
= open(TCP_DEVICE
, O_RDWR
);
72 r
= ioctl(s1
, NWIOGTCPCOOKIE
, &cookie
);
80 r
= ioctl(sock
, NWIOTCPACCEPTTO
, &cookie
);
89 getpeername(s1
, address
, address_len
);
93 static int _uds_accept(int sock
, struct sockaddr
*__restrict address
,
94 socklen_t
*__restrict address_len
)
98 struct sockaddr_un uds_addr
;
101 memset(&uds_addr
, '\0', sizeof(struct sockaddr_un
));
103 r
= ioctl(sock
, NWIOGUDSADDR
, &uds_addr
);
108 if (uds_addr
.sun_family
!= AF_UNIX
) {
114 if (len
> sizeof(struct sockaddr_un
))
115 len
= sizeof(struct sockaddr_un
);
117 memcpy(address
, &uds_addr
, len
);
120 s1
= open(UDS_DEVICE
, O_RDWR
);
124 r
= ioctl(s1
, NWIOSUDSACCEPT
, address
);
126 int ioctl_errno
= errno
;