41#define _POSIX_C_SOURCE 200809L
46#include <netinet/in.h>
50#include <sys/select.h>
51#include <sys/socket.h>
78 struct addrinfo hints, *res;
81 memset(&hints, 0,
sizeof(hints));
82 hints.ai_socktype = SOCK_STREAM;
83 hints.ai_family = AF_INET;
84 hints.ai_flags = AI_PASSIVE;
86 sprintf(service,
"%d", *port);
87 ai_err = getaddrinfo(host, service, &hints, &res);
89 perror(
"Error fetching host data. Wrong host name?");
94 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
96 perror(
"Error opening socket");
101 if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
102 perror(
"Error opening INET socket: wrong port or server unreachable");
107 struct sockaddr_un serv_addr;
110 memset(&serv_addr, 0,
sizeof(serv_addr));
111 serv_addr.sun_family = AF_UNIX;
112 if (strlen(host) >=
sizeof(serv_addr.sun_path)) {
113 fprintf(stderr,
"UNIX socket path is too long\n");
116 strcpy(serv_addr.sun_path, host);
119 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
122 if (connect(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0) {
124 "Error opening UNIX socket: path unavailable, or already existing");
150 struct addrinfo hints, *res;
153 memset(&hints, 0,
sizeof(hints));
154 hints.ai_socktype = SOCK_STREAM;
155 hints.ai_family = AF_INET;
156 hints.ai_flags = AI_PASSIVE;
158 sprintf(service,
"%d", *port);
159 ai_err = getaddrinfo(host, service, &hints, &res);
161 perror(
"Error fetching host data. Wrong host name?");
166 sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
168 perror(
"Error opening socket");
173 if (bind(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
174 perror(
"Error binding INET socket: wrong port or server unreachable");
179 struct sockaddr_un serv_addr;
182 memset(&serv_addr, 0,
sizeof(serv_addr));
183 serv_addr.sun_family = AF_UNIX;
184 if (strlen(host) >=
sizeof(serv_addr.sun_path)) {
185 fprintf(stderr,
"UNIX socket path is too long\n");
188 strcpy(serv_addr.sun_path, host);
191 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
193 remove(serv_addr.sun_path);
196 if (bind(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0) {
198 "Error binding UNIX socket: path unavailable, or already existing");
214 fprintf(stderr,
"Invalid socket write length\n");
217 size_t done = 0, len = (size_t)*plen;
219 ssize_t n = write(*psockfd, data + done, len - done);
220 if (n < 0 && errno == EINTR)
223 perror(
"Error writing to socket: server has quit or connection broke");
238 fprintf(stderr,
"Invalid socket read length\n");
241 size_t done = 0, len = (size_t)*plen;
243 ssize_t n = read(*psockfd, data + done, len - done);
244 if (n < 0 && errno == EINTR)
248 fprintf(stderr,
"Unexpected EOF reading from socket (%zu/%zu bytes)\n",
251 perror(
"Error reading from socket");
266 if (listen(*psockfd, *backlog) < 0) {
267 perror(
"Error listening socket");
279 int client_fd = accept(*psockfd, NULL, NULL);
281 *pclientfd = client_fd;
301 struct timespec wt, rem;
302 wt.tv_sec = floor(*dsec);
303 wt.tv_nsec = (*dsec - wt.tv_sec) * 1000000000;
304 nanosleep(&wt, &rem);
void open_bind_socket(int *psockfd, int *inet, int *port, char *host)
Opens and binds a socket.
void open_connect_socket(int *psockfd, int *inet, int *port, char *host)
Opens and connects a socket.
void writebuffer(int *psockfd, char *data, int *plen)
Writes to a socket.
void accept_socket(int *psockfd, int *pclientfd)
Listens to a socket.
void uwait(double *dsec)
Mini-wrapper to nanosleep.
void close_socket(int *psockfd)
Closes a socket.
void listen_socket(int *psockfd, int *backlog)
Listens to a socket.
void readbuffer(int *psockfd, char *data, int *plen)
Reads from a socket.
void remove_socket_file(char *host)
Removes a socket file.