Backport from xs.

This commit is contained in:
default 2023-09-04 11:13:40 +02:00
parent 8535fc84c9
commit 18c11ab916
2 changed files with 87 additions and 5 deletions

View File

@ -5,9 +5,11 @@
#define _XS_SOCKET_H
int xs_socket_timeout(int s, double rto, double sto);
int xs_socket_server_serv(const char *addr, const char *serv);
int xs_socket_server(const char *addr, int port);
FILE *xs_socket_accept(int rs);
xs_str *xs_socket_peername(int s);
int xs_socket_connect(const char *addr, const char *serv);
#ifdef XS_IMPLEMENTATION
@ -42,8 +44,8 @@ int xs_socket_timeout(int s, double rto, double sto)
}
int xs_socket_server(const char *addr, int port)
/* opens a server socket */
int xs_socket_server_serv(const char *addr, const char *serv)
/* opens a server socket by service name (or port as string) */
{
int rs = -1;
struct sockaddr_in host;
@ -59,8 +61,14 @@ int xs_socket_server(const char *addr, int port)
goto end;
}
struct servent *se;
if ((se = getservbyname(serv, "tcp")) != NULL)
host.sin_port = se->s_port;
else
host.sin_port = htons(atoi(serv));
host.sin_family = AF_INET;
host.sin_port = htons(port);
if ((rs = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
/* reuse addr */
@ -80,6 +88,16 @@ end:
}
int xs_socket_server(const char *addr, int port)
/* opens a server socket (port as integer) */
{
char serv[32];
snprintf(serv, sizeof(serv), "%d", port);
return xs_socket_server_serv(addr, serv);
}
FILE *xs_socket_accept(int rs)
/* accepts an incoming connection */
{
@ -124,6 +142,70 @@ xs_str *xs_socket_peername(int s)
}
int xs_socket_connect(const char *addr, const char *serv)
/* creates a client connection socket */
{
int d = -1;
#ifndef WITHOUT_GETADDRINFO
struct addrinfo *res;
struct addrinfo hints;
memset(&hints, '\0', sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_ADDRCONFIG;
if (getaddrinfo(addr, serv, &hints, &res) == 0) {
struct addrinfo *r;
for (r = res; r != NULL; r = r->ai_next) {
d = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
if (d != -1) {
if (connect(d, r->ai_addr, r->ai_addrlen) == 0)
break;
close(d);
d = -1;
}
}
freeaddrinfo(res);
}
#else /* WITHOUT_GETADDRINFO */
/* traditional socket interface */
struct hostent *he;
if ((he = gethostbyname(addr)) != NULL) {
struct sockaddr_in host;
memset(&host, '\0', sizeof(host));
memcpy(&host.sin_addr, he->h_addr_list[0], he->h_length);
host.sin_family = he->h_addrtype;
struct servent *se;
if ((se = getservbyname(serv, "tcp")) != NULL)
host.sin_port = se->s_port;
else
host.sin_port = htons(atoi(serv));
if ((d = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
if (connect(d, (struct sockaddr *)&host, sizeof(host)) == -1)
d = -1;
}
}
#endif /* WITHOUT_GETADDRINFO */
return d;
}
#endif /* XS_IMPLEMENTATION */
#endif /* _XS_SOCKET_H */

View File

@ -1 +1 @@
/* 9a2b91d7713c862ce8753721da2ab5867abb80fd */
/* fdd04f1862e0d8bdebb7b438798914643895d43f */