add_library(dragonnet
dragonnet/addr.c
+ dragonnet/error.c
dragonnet/init.c
dragonnet/listen.c
dragonnet/peer.c
--- /dev/null
+#include <errno.h>
+#include <stdio.h>
+#include "error.h"
+#include "sock.h"
+
+void dragonnet_perror(const char *str)
+{
+#ifdef _WIN32
+ wchar_t *msg = NULL;
+ FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &msg, 0, NULL);
+ fprintf(stderr, "%s: %S\n", str, msg);
+ LocalFree(msg);
+#else // _WIN32
+ perror(str);
+#endif // _WIN32
+}
+
+bool dragonnet_isconnerr()
+{
+#ifdef _WIN32
+ int err = WSAGetLastError();
+ return err == WSAECONNRESET || err == WSAETIMEDOUT || err == WSAEDISCON;
+#else // _WIN32
+ return errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT;
+#endif // _WIN32
+}
+
+
+bool dragonnet_isintrerr()
+{
+#ifdef _WIN32
+ return WSAGetLastError() == WSAEINTR;
+#else // _WIN32
+ return errno == EINTR;
+#endif // _WIN32
+}
--- /dev/null
+#ifndef _DRAGONNET_ERROR_H_
+#define _DRAGONNET_ERROR_H_
+
+#include <stdbool.h>
+
+void dragonnet_perror(const char *str);
+bool dragonnet_isconnerr();
+bool dragonnet_isintrerr();
+
+#endif
#define _GNU_SOURCE
#include <assert.h>
-#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "addr.h"
+#include "error.h"
#include "listen.h"
#include "recv.h"
#include "sock.h"
DragonnetListener *l = malloc(sizeof *l);
if ((l->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol)) < 0) {
- perror("socket");
+ dragonnet_perror("socket");
freeaddrinfo(info);
free(l);
return NULL;
int so_reuseaddr = 1;
if (setsockopt(l->sock, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr,
sizeof so_reuseaddr) < 0) {
- perror("setsockopt");
+ dragonnet_perror("setsockopt");
freeaddrinfo(info);
dragonnet_listener_delete(l);
return NULL;
}
if (bind(l->sock, info->ai_addr, info->ai_addrlen) < 0) {
- perror("bind");
+ dragonnet_perror("bind");
freeaddrinfo(info);
dragonnet_listener_delete(l);
return NULL;
freeaddrinfo(info);
if (listen(l->sock, 10) < 0) {
- perror("listen");
+ dragonnet_perror("listen");
dragonnet_listener_delete(l);
return NULL;
}
int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen);
if (clt_sock < 0) {
- if (errno != EINTR)
- perror("accept");
+ if (!dragonnet_isintrerr())
+ dragonnet_perror("accept");
continue;
}
#include <stdio.h>
#include <stdlib.h>
#include "addr.h"
+#include "error.h"
#include "peer.h"
#include "recv.h"
#include "recv_thread.h"
return false;
if ((p->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol)) < 0) {
- perror("socket");
+ dragonnet_perror("socket");
freeaddrinfo(info);
return false;
}
p->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
if (connect(p->sock, info->ai_addr, info->ai_addrlen) < 0) {
- perror("connect");
+ dragonnet_perror("connect");
freeaddrinfo(info);
return false;
}
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include "error.h"
#include "recv.h"
#include "sock.h"
ssize_t len = recv(p->sock, buf, n, MSG_WAITALL);
if (len < 0) {
- perror("recv");
+ dragonnet_perror("recv");
abort();
}
#define _GNU_SOURCE
#include <assert.h>
#include <endian.h>
-#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include "error.h"
#include "peer.h"
#include "recv.h"
#include "recv_thread.h"
ssize_t len = recv(p->sock, (void *) &type_id, sizeof type_id, MSG_WAITALL);
if (len < 0) {
- if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
+ if (dragonnet_isconnerr()) {
reset = true;
} else {
- perror("recv");
+ dragonnet_perror("recv");
abort();
}
}
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "error.h"
#include "send.h"
#include "sock.h"
ssize_t len = send(p->sock, buf, n, MSG_NOSIGNAL | (submit ? 0 : MSG_MORE));
if (len < 0) {
- if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
+ if (dragonnet_isconnerr()) {
shutdown(p->sock, SHUT_RDWR);
pthread_mutex_unlock(&p->mtx);
return false;
}
- perror("send");
+ dragonnet_perror("send");
abort();
}