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) {