2 #include <sys/socket.h>
13 int usock(int type
, const char *host
, const char *service
) {
16 if (service
&& !(type
& USOCK_UNIX
)) {
17 struct addrinfo
*result
, *rp
;
19 struct addrinfo hints
= {
20 .ai_family
= (type
& USOCK_IPV6ONLY
) ? AF_INET6
:
21 (type
& USOCK_IPV4ONLY
) ? AF_INET
: AF_UNSPEC
,
22 .ai_socktype
= ((type
& 0xff) == USOCK_TCP
)
23 ? SOCK_STREAM
: SOCK_DGRAM
,
24 .ai_flags
= AI_ADDRCONFIG
25 | ((type
& USOCK_SERVER
) ? AI_PASSIVE
: 0)
26 | ((type
& USOCK_NUMERIC
) ? AI_NUMERICHOST
: 0),
29 if (getaddrinfo(host
, service
, &hints
, &result
)) {
33 for (rp
= result
; rp
!= NULL
; rp
= rp
->ai_next
) {
34 if ((sock
= socket(rp
->ai_family
, rp
->ai_socktype
, rp
->ai_protocol
))
39 if (!(type
& USOCK_NOCLOEXEC
)) {
40 fcntl(sock
, F_SETFD
, fcntl(sock
, F_GETFD
) | FD_CLOEXEC
);
43 if (type
& USOCK_NONBLOCK
) {
44 fcntl(sock
, F_SETFL
, fcntl(sock
, F_GETFL
) | O_NONBLOCK
);
47 if (type
& USOCK_SERVER
) {
49 setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, &one
, sizeof(one
));
51 if (!bind(sock
, rp
->ai_addr
, rp
->ai_addrlen
)
52 && ((type
& 0xff) != USOCK_TCP
|| !listen(sock
, SOMAXCONN
))) {
56 if (!connect(sock
, rp
->ai_addr
, rp
->ai_addrlen
)
57 || errno
== EINPROGRESS
) {
67 struct sockaddr_un sun
= {.sun_family
= AF_UNIX
};
68 if (strlen(host
) >= sizeof(sun
.sun_path
)) {
72 strcpy(sun
.sun_path
, host
);
74 if ((sock
= socket(AF_UNIX
, ((type
& 0xff) == USOCK_TCP
)
75 ? SOCK_STREAM
: SOCK_DGRAM
, 0)) == -1) {
79 if (!(type
& USOCK_NOCLOEXEC
)) {
80 fcntl(sock
, F_SETFD
, fcntl(sock
, F_GETFD
) | FD_CLOEXEC
);
83 if (type
& USOCK_NONBLOCK
) {
84 fcntl(sock
, F_SETFL
, fcntl(sock
, F_GETFL
) | O_NONBLOCK
);
87 if (type
& USOCK_SERVER
) {
88 if (bind(sock
, (struct sockaddr
*)&sun
, sizeof(sun
)) ||
89 ((type
& 0xff) == USOCK_TCP
&& listen(sock
, SOMAXCONN
))) {
94 if (connect(sock
, (struct sockaddr
*)&sun
, sizeof(sun
))
95 && errno
!= EINPROGRESS
) {