aboutsummaryrefslogtreecommitdiff
path: root/client/libacron/net.c
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-07-21 21:47:47 -0700
committerTrumeet <yuuta@yuuta.moe>2022-07-21 21:47:47 -0700
commit609c725cedbeca31ae3aba3a9c39c5030ea1d20f (patch)
tree3c48656480b312ab0ea231a235fc77a47055d5ca /client/libacron/net.c
parent1635741d1def2228a0b29db987612168d283f28d (diff)
downloadacron-609c725cedbeca31ae3aba3a9c39c5030ea1d20f.tar
acron-609c725cedbeca31ae3aba3a9c39c5030ea1d20f.tar.gz
acron-609c725cedbeca31ae3aba3a9c39c5030ea1d20f.tar.bz2
acron-609c725cedbeca31ae3aba3a9c39c5030ea1d20f.zip
fix(libacron/acronc): complete cross-platform build
This patch made several changes to correctly build libac on Windows: 1. Deprecated PkgConfig on Unix. On both platforms, libac requires the JSON-C CMake module to locate libraries (whether is dynamic or static) and headers. On Windows, the common practice is to statically link the library, so libac now provides setup.bat to automatically clone JSON-C and build it. In CMakeLists.txt, libac will automatically pick up the in-tree JSON-C build if it presents. Otherwise, it will use the system default's. Users can override the CMAKE_PREFIX_PATH to supply a custom JSON-C library if it is not found in-tree. 2. Switched from #include <json-c/xxx.h> to <xxx.h>, as the former (current) approach is non-standard and depends on the system header locations. The later (new) approach relies on CMake to supply header search paths, which works on Windows as well. 3. Deprecated --version-script on Unix linkers. Instead, libac now uses -fvisibility (https://gcc.gnu.org/wiki/Visibility) on GCC or LLVM, as well as __declspec(dllexport) on MSVC to export selected symbols. A new macro, LIBAC_EXPORT, is defined in incl.h (new), and all functions needed to export are marked with that macro. 4. Changed several codes (mostly socket-related) to work on Windows. 5. Massive rewrite of CMake in preparation of further installation and static library support. Signed-off-by: Trumeet <yuuta@yuuta.moe>
Diffstat (limited to 'client/libacron/net.c')
-rw-r--r--client/libacron/net.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/client/libacron/net.c b/client/libacron/net.c
index cab4625..a0e8659 100644
--- a/client/libacron/net.c
+++ b/client/libacron/net.c
@@ -2,6 +2,7 @@
* Created by yuuta on 7/13/22.
*/
+#include "win32.h"
#include "config.h"
#include "net.h"
#include "connection.h"
@@ -15,11 +16,17 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <sys/socket.h>
+#include <netdb.h>
#include <unistd.h>
+#endif
static void on_open_handler(struct wic_inst *inst) {
struct ac_connection *conn = wic_get_app(inst);
@@ -32,12 +39,13 @@ static void on_send_handler(struct wic_inst *inst,
enum wic_buffer type) {
struct ac_connection *conn = wic_get_app(inst);
size_t pos;
- ssize_t retval;
+ const uint8_t *ptr = data;
+ int retval;
for (pos = 0U; pos < size; pos += retval) {
size_t n = size - pos;
LOGDV("write(%d, %p[%u, %u])", conn->fd, data, pos, n);
- retval = write(conn->fd, &data[pos], (int) n);
+ retval = (int) send(conn->fd, &ptr[pos], (int) n, 0);
if (retval <= 0) {
/* There's no way to abort the process. */
int e = errno;
@@ -154,13 +162,18 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) {
}
if ((r = getaddrinfo(host, service, NULL, &res))) {
+ /* gai_strerror() seems to cause an linkage error. */
+#ifdef WIN32
+ LOGEV("Resolve host: %d.", r);
+#else
LOGEV("Resolve host: %s.", gai_strerror(r));
+#endif
r = AC_E_NET;
free(conn);
return r;
}
- int fd;
+ SOCKET fd;
if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) <= 0) {
const int e = errno;
LOGEV("Cannot create socket: %s (%d).",
@@ -171,11 +184,17 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) {
return AC_E_NET;
}
if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
+#ifdef WIN32
+ const int e = WSAGetLastError();
+ LOGEV("Cannot connect to socket: %d.",
+ e);
+#else
const int e = errno;
LOGEV("Cannot connect to socket: %s (%d).",
strerror2(e),
e);
- close(fd);
+#endif
+ closesocket(fd);
freeaddrinfo(res);
free(conn);
return AC_E_NET;
@@ -185,7 +204,7 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) {
conn->fd = fd;
if (wic_start(inst) != WIC_STATUS_SUCCESS) {
LOGE("Cannot start the WIC client.");
- close(fd);
+ closesocket(fd);
free(conn);
return AC_E_NET;
}
@@ -193,7 +212,7 @@ int ac_connect(ac_connection_parameters_t parameters, void **out) {
/* Wait until established (ready to send). */
while (!conn->established) {
ac_obj_t *obj = NULL;
- r = ac_receive(conn, &obj);
+ r = ac_receive(conn, &obj, 0);
if (obj) {
LOGW("Received an object before connection is established. Dropping.");
ac_object_free(obj);
@@ -216,7 +235,7 @@ int ac_disconnect(void *connection) {
}
LOGD("Disconnecting...");
wic_close(&conn->inst);
- close(conn->fd);
+ closesocket(conn->fd);
free(conn);
return AC_E_OK;
}
@@ -227,13 +246,18 @@ int ac_receive(void *connection, ac_obj_t **response) {
struct wic_inst *inst = &conn->inst;
static uint8_t buffer[1000U];
- ssize_t bytes;
+ int bytes;
size_t retval, pos;
- if ((bytes = recv(conn->fd, buffer, sizeof(buffer), 0)) <= 0) {
+ if ((bytes = (int) recv(conn->fd, buffer, sizeof(buffer), 0)) <= 0) {
LOGDV("recv(%d) = %d", conn->fd, bytes);
if (bytes < 0) {
const int e = errno;
+ if (e == EAGAIN) {
+ /* Timeout */
+ *response = NULL;
+ return AC_E_OK;
+ }
LOGEV("Failed to receive from socket : %s (%d).",
strerror2(e),
e);