1 HEADER #include <netdb.h>
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <netinet/tcp.h>
10 HEADER extern const struct addrinfo libjh_tcp_hints;
11 HEADER #define JH_TCP_HINTS (&libjh_tcp_hints)
12 const struct addrinfo libjh_tcp_hints = {
13 .ai_flags = AI_ADDRCONFIG,
14 .ai_family = AF_UNSPEC,
15 .ai_socktype = SOCK_STREAM,
19 // negative return value: interpret as a getaddrinfo() error (non-gai errors become EAI_SYSTEM)
20 // >=0 return value: interpret as resulting fd
21 PUBLIC_FN int netopen(const char *node, const char *service, const struct addrinfo *hints) {
22 struct addrinfo *addrs;
23 int gai_res = getaddrinfo(node, service, hints, &addrs);
24 if (gai_res) return gai_res;
26 int s = socket(addrs[0].ai_family, addrs[0].ai_socktype, addrs[0].ai_protocol);
27 if (s == -1) goto err_socket;
29 if (connect(s, addrs[0].ai_addr, addrs[0].ai_addrlen)) goto err_connect;
43 PUBLIC_FN int fnetopen(FILE **in, FILE **out, const char *node, const char *service, const struct addrinfo *hints) {
44 int fd = netopen(node, service, hints);
45 if (fd < 0) return EAI_SYSTEM;
46 int ret = fopen_bistream(in, out, fd, 0);
51 HEADER // negative return value for error, else a socket
52 PUBLIC_FN int netopen_server(const char *node /*NULL for ANY*/, const char *service, const struct addrinfo *hints) {
53 struct addrinfo hints_;
54 if (hints == &libjh_tcp_hints) {
56 hints_.ai_flags |= AI_PASSIVE;
57 hints_.ai_flags &= ~AI_ADDRCONFIG;
61 struct addrinfo *addrs;
62 int gai_res = getaddrinfo(node, service, hints, &addrs);
63 if (gai_res) return gai_res;
65 int s = socket(addrs[0].ai_family, addrs[0].ai_socktype, addrs[0].ai_protocol);
66 if (s == -1) goto err_socket;
68 if (bind(s, addrs[0].ai_addr, addrs[0].ai_addrlen)) goto err_bind_n_listen;
69 if (listen(s, 16)) goto err_bind_n_listen;