diff --git a/CMakeLists.txt b/CMakeLists.txt index a08ca4cb341e5726619aea870260f05503934f2c..2fc80a4e3d52b554cd3fdd051e64168943070104 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/utils/cmake/") set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(THREADS_PREFER_PTHREAD_FLAG ON) set(CMAKE_COLOR_MAKEFILE ON) +SET(CMAKE_COLOR_MAKEFILE ON) include(TestBigEndian) # Needed for endianness tests include(FindOpenMP) # Test OpenMP support @@ -113,9 +114,10 @@ endif() # Don't forget for specific things if(WIN32) message(STATUS "You are building on windows, pay attenion to the dependencies") + find_package(dlfcn-win32 REQUIRED) set(GENERATE_MANPAGES 0) set(LKT_OS_WIN 1) - add_compile_definitions(LKT_OS_WIN=1) + add_compile_definitions(LKT_OS_WIN=1 TERMIWIN_DONOTREDEFINE) endif() if(MSVC OR MSYS OR MINGW) message(STATUS "You are building with a windows compiler") @@ -230,6 +232,7 @@ set(luka_SOURCES set(common_DEFINITIONS LKT_ARCH="${CMAKE_SYSTEM_PROCESSOR}" LKT_MAN_BINARY="${MAN}" + LKT_HAS_MAN=${GENERATE_MANPAGES} LKT_ENDIANES_BIG=${LKT_ENDIANES_BIG} LKT_ENDIANES_LITTLE=${LKT_ENDIANES_LITTLE} LKT_STATIC_MODULE=1 # Only build static modules with cmake @@ -317,6 +320,12 @@ target_link_libraries(lkt PRIVATE ${OpenMP_C_LIBRARIES} ) +if(WIN32) + target_link_libraries(lektord PRIVATE regex dlfcn-win32::dl ws2_32) + target_link_libraries(luka PRIVATE regex dlfcn-win32::dl ws2_32) + target_link_libraries(lkt PRIVATE ws2_32) +endif() + target_include_directories(lkt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc) target_include_directories(luka PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc diff --git a/inc/lektor/config.h b/inc/lektor/config.h index ad0a452254b65893ee1b0f8de901e54793bd0037..4c1b8349282cfcc4f0239eacebbb5eb762227c5d 100644 --- a/inc/lektor/config.h +++ b/inc/lektor/config.h @@ -34,8 +34,13 @@ int config_open(lkt_db *db, char *maybe_conf, size_t maybe_conf_len); void config_default(FILE *output); /* Manipulate Environment Variables */ +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) +#define env_set(var, val) SetEnvironmentVariable(var, val) +#define env_get getenv +#else #define env_set(var, val) setenv(var, val, 1) #define env_get getenv +#endif /* Handle everything for a hook */ void config_handle_hook(lkt_db *db, const char *hook_name); diff --git a/inc/lektor/internal/os.h b/inc/lektor/internal/os.h index c2f6d62dfb69988a4534c286e1ff4d336161e88f..80bd2640394dd3f9169f042b794980bf2292c3b5 100644 --- a/inc/lektor/internal/os.h +++ b/inc/lektor/internal/os.h @@ -25,21 +25,35 @@ extern "C" { #include <time.h> #include <ctype.h> -#if defined(LKT_OS_TOASTER) && (LKT_OS_TOASTER == 1) +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) +#include "lektor/internal/win32/dirent.h" +#include "lektor/internal/win32/endian.h" +#include <processthreadsapi.h> +#include <windows.h> + +#else #include <linux/limits.h> #include <dirent.h> #include <fcntl.h> #include <endian.h> +#include <netdb.h> +#include <poll.h> +#include <arpa/inet.h> +#include <netinet/in.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/time.h> -#endif - -#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) -#include "lektor/internal/win32/dirent.h" -#include "lektor/internal/win32/endian.h" -#include "lektor/internal/win32/termios.h" -#endif +#include <sys/un.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/sysinfo.h> +#include <wait.h> +#include <dlfcn.h> +#include <pwd.h> +#include <spawn.h> +#include <execinfo.h> + +#endif /* defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) */ #if !(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) #error "Unsuported endiannes" @@ -71,6 +85,21 @@ enum { #define DT_WHT DT_WHT #endif +#if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) +typedef int SOCKET; +#define closesocket(fd) close(fd) +#define INVALID_SOCKET (-1) + +#else /* LKT_OS_WIN */ +#define SHUT_RDWR SD_BOTH +#define close _close +#define open _open +#define fdopen _fdopen +#define mkdir(str, perm) _mkdir(str) +#define socket(dom, type, proto__) WSASocket(dom, type, 0, 0, 0, 0) + +#endif + typedef void (*function_ptr)(void); /* Attributes */ @@ -148,6 +177,55 @@ uint32_t be_uint32_t(const uint8_t bytes[], size_t n); 'correct'-endian. Restriction: n <= 8 */ uint64_t be_uint64_t(const uint8_t bytes[], size_t n); +/* Get the last system error, errno on UNIX systems */ +PRIVATE_FUNCTION int +get_last_error(void) +{ +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return WSAGetLastError(); +#else + return errno; +#endif +} + +PRIVATE_FUNCTION bool +is_error_would_block(int error) +{ +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return error == WSAEWOULDBLOCK; +#else + return (error == EWOULDBLOCK || error == EAGAIN); +#endif +} + +PRIVATE_FUNCTION bool +is_error_connection_aborted(int error) +{ +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return error == WSAECONNRESET; +#else + return (error == ECONNABORTED); +#endif +} + +PRIVATE_FUNCTION bool +is_error_broken_pipe(int error) +{ +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return false; +#else + return (error == EPIPE); +#endif +} + +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + PRIVATE_FUNCTION int + poll(struct pollfd fds[], nfds_t nfds, int timeout) + { + return WSAPoll(fds, nfds, timeout); + } + #endif + #if defined(__cplusplus) } #endif diff --git a/inc/lektor/internal/win32/termios.h b/inc/lektor/internal/win32/termios.h deleted file mode 100644 index f5620790d8c0194e18660c6e7cb028244ee992ee..0000000000000000000000000000000000000000 --- a/inc/lektor/internal/win32/termios.h +++ /dev/null @@ -1,236 +0,0 @@ -/* termiWin.h -* -* Copyright (C) 2017 Christian Visintin - christian.visintin1997@gmail.com -* -* This file is part of "termiWin: a termios porting for Windows" -* -* termiWin is free software: you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* termiWin is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with termiWin. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -#ifndef TERMIWIN_H_ -#define TERMIWIN_H_ - -#define TERMIWIN_VERSION "1.2.0" -#define TERMIWIN_MAJOR_VERSION 1 -#define TERMIWIN_MINOR_VERSION 2 - -#ifdef _WIN32 -#pragma message(TODO "coucou") - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <winsock2.h> -#pragma comment(lib, "Ws2_32.lib") - -/*Redefining functions from winsock to termiWin. This is very important since winsock2 defines functions such as close as closesocket we have to redefine it*/ - -#ifndef TERMIWIN_DONOTREDEFINE -#define read read_serial -#define write serial_write -#define open open_serial -#define close close_serial -#define select select_serial -#endif - -// ssize_t -#if SIZE_MAX == UINT_MAX -typedef int ssize_t; /* common 32 bit case */ -#define SSIZE_MIN INT_MIN -#define SSIZE_MAX INT_MAX -#elif SIZE_MAX == ULONG_MAX -typedef long ssize_t; /* linux 64 bits */ -#define SSIZE_MIN LONG_MIN -#define SSIZE_MAX LONG_MAX -#elif SIZE_MAX == ULLONG_MAX -typedef long long ssize_t; /* windows 64 bits */ -#define SSIZE_MIN LLONG_MIN -#define SSIZE_MAX LLONG_MAX -#endif - -//Serial options - Linux -> Windows - -/*setAttr flags - ~ in front of flags -> deny them*/ - -//iFlag - -#define INPCK \ - 0x00004000 /*If this bit is set, input parity checking is enabled. If it is not set, no checking at all is done for parity errors on input; the characters are simply passed through to the application.*/ -#define IGNPAR \ - 0x00001000 /*If this bit is set, any byte with a framing or parity error is ignored. This is only useful if INPCK is also set.*/ -#define PARMRK \ - 0x00040000 /*If this bit is set, input bytes with parity or framing errors are marked when passed to the program. This bit is meaningful only when INPCK is set and IGNPAR is not set.*/ -#define ISTRIP \ - 0x00008000 /*If this bit is set, valid input bytes are stripped to seven bits; otherwise, all eight bits are available for programs to read. */ -#define IGNBRK 0x00000400 /*If this bit is set, break conditions are ignored. */ -#define BRKINT \ - 0x00000100 /*If this bit is set and IGNBRK is not set, a break condition clears the terminal input and output queues and raises a SIGINT signal for the foreground process group associated with the terminal. */ -#define IGNCR \ - 0x00000800 /*If this bit is set, carriage return characters ('\r') are discarded on input. Discarding carriage return may be useful on terminals that send both carriage return and linefeed when you type the RET key. */ -#define ICRNL \ - 0x00000200 /*If this bit is set and IGNCR is not set, carriage return characters ('\r') received as input are passed to the application as newline characters ('\n').*/ -#define INLCR \ - 0x00002000 /*If this bit is set, newline characters ('\n') received as input are passed to the application as carriage return characters ('\r').*/ -#define IXOFF \ - 0x00010000 /*If this bit is set, start/stop control on input is enabled. In other words, the computer sends STOP and START characters as necessary to prevent input from coming in faster than programs are reading it. The idea is that the actual terminal hardware that is generating the input data responds to a STOP character by suspending transmission, and to a START character by resuming transmission.*/ -#define IXON \ - 0x00020000 /*If this bit is set, start/stop control on output is enabled. In other words, if the computer receives a STOP character, it suspends output until a START character is received. In this case, the STOP and START characters are never passed to the application program. If this bit is not set, then START and STOP can be read as ordinary characters.*/ - -//lFlag - -#define ICANON \ - 0x00001000 /*This bit, if set, enables canonical input processing mode. Otherwise, input is processed in noncanonical mode. */ -#define ECHO \ - 0x00000100 /*If this bit is set, echoing of input characters back to the terminal is enabled.*/ -#define ECHOE \ - 0x00000200 /*If this bit is set, echoing indicates erasure of input with the ERASE character by erasing the last character in the current line from the screen. Otherwise, the character erased is re-echoed to show what has happened (suitable for a printing terminal). */ -#define ECHOK \ - 0x00000400 /*This bit enables special display of the KILL character by moving to a new line after echoing the KILL character normally. The behavior of ECHOKE (below) is nicer to look at.*/ -#define ECHONL \ - 0x00000800 /*If this bit is set and the ICANON bit is also set, then the newline ('\n') character is echoed even if the ECHO bit is not set. */ -#define ISIG \ - 0x00004000 /*This bit controls whether the INTR, QUIT, and SUSP characters are recognized. The functions associated with these characters are performed if and only if this bit is set. Being in canonical or noncanonical input mode has no effect on the interpretation of these characters. */ -#define IEXTEN \ - 0x00002000 /*On BSD systems and GNU/Linux and GNU/Hurd systems, it enables the LNEXT and DISCARD characters.*/ -#define NOFLSH \ - 0x00008000 /*Normally, the INTR, QUIT, and SUSP characters cause input and output queues for the terminal to be cleared. If this bit is set, the queues are not cleared. */ -#define TOSTOP \ - 0x00010000 /*If this bit is set and the system supports job control, then SIGTTOU signals are generated by background processes that attempt to write to the terminal.*/ - -//cFlag - -#define CSTOPB \ - 0x00001000 /*If this bit is set, two stop bits are used. Otherwise, only one stop bit is used. */ -#define PARENB \ - 0x00004000 /*If this bit is set, generation and detection of a parity bit are enabled*/ -#define PARODD \ - 0x00008000 /*This bit is only useful if PARENB is set. If PARODD is set, odd parity is used, otherwise even parity is used. */ -#define CSIZE 0x00000c00 /*This is a mask for the number of bits per character. */ -#define CS5 0x00000000 /*This specifies five bits per byte. */ -#define CS6 0x00000400 /*This specifies six bits per byte. */ -#define CS7 0x00000800 /*This specifies seven bits per byte. */ -#define CS8 0x00000c00 /*This specifies eight bits per byte. */ -#define CLOCAL \ - 0x00000000 /*Ignore modem control lines -> ignore data carrier detected - not implementable in windows*/ -#define CREAD 0x00000000 /*Enable receiver - if is not set no character will be received*/ - -//oFlag - -#define OPOST \ - 0x00000100 /*If this bit is set, output data is processed in some unspecified way so that it is displayed appropriately on the terminal device. This typically includes mapping newline characters ('\n') onto carriage return and linefeed pairs. */ - -//cc - -#define VEOF 0 -#define VEOL 1 -#define VERASE 2 -#define VINTR 3 -#define VKILL 4 -#define VMIN 5 /*If set to 0, serial communication is NOT-BLOCKING, otherwise is BLOCKING*/ -#define VQUIT 6 -#define VSTART 7 -#define VSTOP 8 -#define VSUSP 9 -#define VTIME 10 - -//END OF setAttr flags - -/*Controls*/ -#define TIOMBIC DTR_CONTROL_DISABLE -#define TIOMBIS DTR_CONTROL_ENABLE -#define CRTSCTS RTS_CONTROL_ENABLE - -/*Others*/ -#define NCCS 11 - -//Baud speed -#define B110 CBR_110 -#define B300 CBR_300 -#define B600 CBR_600 -#define B1200 CBR_2400 -#define B2400 CBR_2400 -#define B4800 CBR_4800 -#define B9600 CBR_9600 -#define B19200 CBR_19200 -#define B38400 CBR_38400 -#define B57600 CBR_57600 -#define B115200 CBR_115200 - -/*Attributes optional_actions*/ -#define TCSANOW 0 -#define TCSADRAIN 1 -#define TCSAFLUSH 2 - -/*TCFLUSH options*/ -#define TCIFLUSH 0 -#define TCOFLUSH 1 -#define TCIOFLUSH 2 - -/*TCFLOW optons*/ - -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - -//typdef -typedef unsigned - tcflag_t; /*This is an unsigned integer type used to represent the various bit masks for terminal flags.*/ -typedef unsigned - cc_t; /*This is an unsigned integer type used to represent characters associated with various terminal control functions.*/ -typedef unsigned speed_t; /*used for terminal baud rates*/ - -typedef struct termios { - tcflag_t c_iflag; /*input modes*/ - tcflag_t c_oflag; /*output modes*/ - tcflag_t c_cflag; /*control modes*/ - tcflag_t c_lflag; /*local modes*/ - cc_t c_cc[NCCS]; /*special character*/ - -} termios; - -//Serial configuration functions - -int tcgetattr(int fd, struct termios *termios_p); -int tcsetattr(int fd, int optional_actions, const struct termios *termios_p); -int tcsendbreak(int fd, int duration); -int tcdrain(int fd); -int tcflush(int fd, int queue_selector); -int tcflow(int fd, int action); -void cfmakeraw(struct termios *termios_p); -speed_t cfgetispeed(const struct termios *termios_p); -speed_t cfgetospeed(const struct termios *termios_p); -int cfsetispeed(struct termios *termios_p, speed_t speed); -int cfsetospeed(struct termios *termios_p, speed_t speed); -int cfsetspeed(struct termios *termios_p, speed_t speed); - -//Write/Read/Open/Close/Select Functions - -ssize_t read_serial(int fd, void *buffer, size_t count); -ssize_t write_serial(int fd, const void *buffer, size_t count); -int open_serial(const char *portname, int opt); -int close_serial(int fd); -int select_serial(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, - struct timeval *timeout); - -//get Handle out of the COM structure -HANDLE getHandle(); - -#endif - -#ifndef _WIN32 -#pragma message("-Warning: termiWin requires a Windows system!") -#endif - -#endif diff --git a/inc/lektor/internal/worker.h b/inc/lektor/internal/worker.h index 04e4cdd795774e1a59a71884840524c3070435c6..c781b5820e53d8eb6ce3e61c602fbf0665b004e8 100644 --- a/inc/lektor/internal/worker.h +++ b/inc/lektor/internal/worker.h @@ -1,7 +1,6 @@ #pragma once #include <lektor/common.h> -#include <sys/sysinfo.h> #include <sched.h> #include <pthread.h> #include <stdlib.h> @@ -81,7 +80,11 @@ worker_pool_thread(void *___pool) --(pool->thread_working); assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); } + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) pthread_exit(NULL); + #else + return NULL; + #endif } PRIVATE_FUNCTION WORKER_STATUS @@ -121,7 +124,11 @@ PRIVATE_FUNCTION int worker_pool_new(struct worker_pool *ret, size_t init_size, size_t thread_count) { if (!thread_count) { - int nprocs = get_nprocs_conf(); + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) + const int nprocs = get_nprocs_conf(); + #else + const int nprocs = 2; + #endif assert(nprocs > 0); thread_count = (size_t)nprocs; } diff --git a/inc/lektor/net.h b/inc/lektor/net.h index a4d67275f1da3088d811831acdcc91dca8346fa4..e503f9483068f3f9f4ce6579097ed6262b4d03e0 100644 --- a/inc/lektor/net.h +++ b/inc/lektor/net.h @@ -1,5 +1,4 @@ -#if !defined(LKT_NET_H__) -#define LKT_NET_H__ +#pragma once #if defined(__cplusplus) extern "C" { @@ -16,6 +15,10 @@ extern "C" { #include <mpv/client.h> #include <curl/curl.h> +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 256 +#endif // HOST_NAME_MAX + struct lkt_state; struct lkt_command { bool was_truncated; @@ -47,10 +50,17 @@ void lkt_message_free(struct lkt_message *const msg); /* Send a Message into a file descriptor. You need to check the returned value * and errno manually if n <= 0 as you would when calling the 'send' function. * This is only a wrapper for 'send(fd, data, len, MSG_NOSIGNAL)'. */ -int lkt_message_send(int fd, const struct lkt_message *const msg); +int lkt_message_send(SOCKET fd, const struct lkt_message *const msg); struct lkt_state { + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + /* The FDS, Windob' version */ + fd_set *fds; + #else + /* The FDS, toaster OS version */ struct pollfd *fds; + #endif + struct lkt_client *clients; size_t fds_len; size_t fds_max; @@ -112,4 +122,3 @@ void lkt_close_server(struct lkt_state *srv); #if defined(__cplusplus) } #endif -#endif /* LKT_NET_H__ */ diff --git a/src/base/cmd.c b/src/base/cmd.c index 711ddedbcd604249a785422866376764348ddc7d..8d4460e559650a88e7dbbf6ef8a538f0699cfb17 100644 --- a/src/base/cmd.c +++ b/src/base/cmd.c @@ -1,6 +1,5 @@ #include <lektor/common.h> #include <lektor/cmd.h> -#include <wait.h> static const char *executable_name = NULL; @@ -29,7 +28,8 @@ ___cleanup_executable_name(void) EXIT_FUNCTION print_help(void) { - if (!executable_name) +#if defined(LKT_HAS_MAN) && (LKT_HAS_MAN == 1) + if (!executable_name) exit(EXIT_FAILURE); pid_t child_pid = fork(); @@ -55,6 +55,10 @@ print_help(void) } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus)); exit(EXIT_SUCCESS); } + +#else + exit(EXIT_SUCCESS); +#endif } PRIVATE_FUNCTION size_t diff --git a/src/base/commands.c b/src/base/commands.c index 54ac40dd9935427e1155d81a08b133303e4f2bf4..db2a2d1cb945efba2e018d4b41dda7d1b34f5e17 100644 --- a/src/base/commands.c +++ b/src/base/commands.c @@ -5,10 +5,9 @@ #include <lektor/uri.h> #include <lektor/cmd.h> #include <lektor/stb/ds.h> -#include <poll.h> bool -command_restart(struct lkt_state *srv, size_t c, char UNUSED *__argv[LKT_MESSAGE_ARGS_MAX], +command_restart(struct lkt_state *srv, size_t c, char UNUSED *argv__[LKT_MESSAGE_ARGS_MAX], int UNUSED cont) { const char *const argv[] = { cmd_get_executable_name(), NULL }; diff --git a/src/base/common.c b/src/base/common.c index b5cae9f78bdd86917f9ef0e8d7e30187de36c767..fd2603450f2bbaa917d441bf23fa392933a04b7c 100644 --- a/src/base/common.c +++ b/src/base/common.c @@ -112,7 +112,7 @@ ___lkt_log(LOG_LEVEL level, const char *section, const char *func, const char *f char formated_line[LKT_MESSAGE_MAX]; va_start(ap, format); safe_vsnprintf(formated_line, LKT_MESSAGE_MAX, line, ap); - write(2, formated_line, strlen(formated_line)); + write(2, formated_line, (unsigned int)strlen(formated_line)); if (___log_logfile != NULL) lkt_logfile_write(___log_logfile, formated_line); va_end(ap); diff --git a/src/base/config.c b/src/base/config.c index 08deb3046104f29806afb52bbd7d1c77b39562c7..973916f84dfb799a2fee23baf7e3255f00cc4371 100644 --- a/src/base/config.c +++ b/src/base/config.c @@ -5,9 +5,6 @@ #include <lektor/reg.h> #include <lektor/lib/strv.h> -#include <dlfcn.h> -#include <pwd.h> - /* Get the path to the config file that may be red, taking into account the priority between existing files. The returned path is a path to an existing file. If no file is found, returns a non zero value. Returns 1 otherwise. */ @@ -215,16 +212,19 @@ PRIVATE_FUNCTION int config_detect_file(char *conf, size_t conf_len) { bool is_malloc = false; - struct passwd *pw = getpwuid(getuid()); char *home; + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) + struct passwd *pw = getpwuid(getuid()); + #endif + if (conf == NULL) return 1; memset(conf, 0, conf_len * sizeof(char)); /* Try the current working dir config file. */ - if (getcwd(conf, conf_len - 1) != NULL) { + if (getcwd(conf, (size_t)(conf_len) - 1) != NULL) { strncat(conf, "/lektor.ini", conf_len - 1); LOG_INFO("CONFIG", "Trying %s", conf); if (!access(conf, R_OK | F_OK)) @@ -242,8 +242,10 @@ config_detect_file(char *conf, size_t conf_len) } if (!home || (strlen(home) >= conf_len)) home = getenv("HOME"); + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) if (!home || (strlen(home) >= conf_len)) home = pw->pw_dir; + #endif if (!home || (strlen(home) >= conf_len)) goto no_config_directory; memcpy(conf, home, (strlen(home) + 1) * sizeof(char)); @@ -326,7 +328,7 @@ ___mkdir(const char *dir) for (p = tmp + 1; *p; p++) { if (*p == '/') { *p = 0; - mkdir(tmp, 00700); + mkdir(tmp, 0700); *p = '/'; } } diff --git a/src/base/launch.c b/src/base/launch.c index 1013fb1b93fb81d029db0a95e13e3c8cf616bf90..cf6a28dbfaa8fb5e0658562a0a733cb7b93101df 100644 --- a/src/base/launch.c +++ b/src/base/launch.c @@ -6,9 +6,7 @@ #include <lektor/config.h> #include <lektor/launch.h> -#include <wait.h> #include <signal.h> -#include <spawn.h> #include <libgen.h> /* The environment */ @@ -34,7 +32,7 @@ resolve_path(void) char *self_dir = dirname(exe_path); LOG_DEBUG("INIT", "Try to patch PATH with %s", self_dir); safe_snprintf(new_path, PATH_MAX, "%s:%s", self_dir, env_PATH); - GOTO_IF(setenv("PATH", new_path, 1), "Failed to set new PATH", error); + GOTO_IF(!env_set("PATH", new_path), "Failed to set new PATH", error); env_PATH = getenv("PATH"); LOG_DEBUG("INIT", "PATH is: %s", env_PATH); return; @@ -65,7 +63,8 @@ resolve_appimage(void) DESTRUCTOR_FUNCTION ___kill_klkt(void) { - RETURN_UNLESS(___klkt_pid, "No klkt child process to wait for", NOTHING) + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) + RETURN_UNLESS(___klkt_pid, "No klkt child process to wait for", NOTHING) if (kill(___klkt_pid, SIGTERM) != 0) { kill(___klkt_pid, SIGKILL); @@ -91,6 +90,8 @@ ___kill_klkt(void) : 0); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + #endif + return; } /* Callable functions */ @@ -98,7 +99,8 @@ ___kill_klkt(void) int launch_ext_klkt(va_list UNUSED *___args) { - char exe_path[LKT_LINE_MAX]; + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) + char exe_path[LKT_LINE_MAX]; char try_name[LKT_LINE_MAX]; const char *const appimage = getenv("APPIMAGE"); char *args[] = { "klkt", NULL }; @@ -170,6 +172,8 @@ error: end: LOG_INFO("INIT", "Klkt launched with pid %ld", ___klkt_pid, try_name); posix_spawn_file_actions_destroy(&action); + + #endif return 0; } diff --git a/src/base/logfile.c b/src/base/logfile.c index 18755adcb96377bfb1005fde7a4674f59754f260..d6f2bcd32bc2a133ed1e0ae6c6b1583b91d0c52b 100644 --- a/src/base/logfile.c +++ b/src/base/logfile.c @@ -37,8 +37,14 @@ PRIVATE_FUNCTION void ___close_all_files(struct lkt_logfile *logfile) { if (logfile->current_fd > 0) { +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + //HANDLE handle = _get_osfhandle(logfile->current_fd); TODO: FIXME + //FlushFileBuffers(handle); + _close(logfile->current_fd); +#else fsync(logfile->current_fd); close(logfile->current_fd); + #endif } } @@ -121,7 +127,7 @@ lkt_logfile_write(struct lkt_logfile *logfile, const char *line) { if (logfile->current_lines_in_file >= logfile->line_count) ___rotate_logfile(logfile); - write(logfile->current_fd, line, strlen(line)); + write(logfile->current_fd, line, (unsigned int)(strlen(line))); ++(logfile->current_lines_in_file); } @@ -130,7 +136,13 @@ lkt_logfile_vfwrite(struct lkt_logfile *logfile, const char *line, va_list ap) { if (logfile->current_lines_in_file >= logfile->line_count) ___rotate_logfile(logfile); - vdprintf(logfile->current_fd, line, ap); + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + FILE *f = _fdopen(logfile->current_fd, "a"); + vfprintf(f, line, ap); + fclose(f); + #else + vdprintf(logfile->current_fd, line, ap); + #endif ++(logfile->current_lines_in_file); } diff --git a/src/base/os.c b/src/base/os.c index 9c91f2e429d26f03df225699b3d6a1e1f215cbf1..6243ec6421651010f6ad699a95ed4fa58e2fe67e 100644 --- a/src/base/os.c +++ b/src/base/os.c @@ -12,14 +12,20 @@ int lkt_read_self_exe(char *path, size_t len) { +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return !GetModuleFileName(NULL, path, (DWORD)len-1); // Error checking : https://stackoverflow.com/questions/9112893/how-to-get-path-to-executable-in-c-running-on-windows + #else return !((readlink(SELF_EXECUTABLE_LINUX, path, len - 1) > 0) || (readlink(SELF_EXECUTABLE_FREEBSD, path, len - 1) > 0) || (readlink(SELF_EXECUTABLE_SOLARIS, path, len - 1) > 0)); + #endif } void lkt_thread_set_name(const char *name) { +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) +#else const size_t len = strlen(name); if (len >= 16) { LOG_FATAL("The name should at most be a 15 character string! Here the length is %zu", len); @@ -34,10 +40,11 @@ lkt_thread_set_name(const char *name) assert(0 == thr_self(&id)); LOG_INFO("OS", "Set name to '%s' for thread %ld", name, id); assert(0 == thr_set_name(id, name)); -#else +#else /* Unknown toaster OS */ #pragma message(TODO "Add support for thread set name for the current OS") LOG_ERROR("OS", "Unsuported operation 'thread_set_name' for OS"); #endif + #endif /* defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) */ } /* Endian stuff */ diff --git a/src/base/segv.c b/src/base/segv.c index f61278298d5e22c59f63134c6ce3a0cebc870a10..fe38d59633c8492b9b7b7f96ff27a8319ad49043 100644 --- a/src/base/segv.c +++ b/src/base/segv.c @@ -2,7 +2,6 @@ #include <lektor/common.h> #include <lektor/segv.h> -#include <execinfo.h> #include <signal.h> #define BT_BUF_SIZE 100 @@ -17,9 +16,11 @@ ___segv_handler(int sig) if (___install_segv_handler_verbose != 1) return; + LOG_ERROR("SEGV", "Got signal %d", sig); + + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) void *buffer[LKT_BACKLOG]; int nptrs = backtrace(buffer, LKT_BACKLOG); - LOG_ERROR("SEGV", "Got signal %d", sig); char **strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { @@ -31,6 +32,8 @@ ___segv_handler(int sig) LOG_ERROR("SEGV", "[%2d] %s", j, strings[j]); free(strings); + #endif + exit(EXIT_FAILURE); } diff --git a/src/database/cache.c b/src/database/cache.c index 18deada8944d955d7f467269e21a8f5afd245460..8b6a0e1a181d282f5061226301a82bf2e01f9a8c 100644 --- a/src/database/cache.c +++ b/src/database/cache.c @@ -31,7 +31,7 @@ PRIVATE_FUNCTION long get_mtime(const char *path) { struct stat statbuf = { 0 }; - return (stat(path, &statbuf) == -1) ? 0 : statbuf.st_mtime; + return (stat(path, &statbuf) == -1) ? 0l : (long)(statbuf.st_mtime); } PRIVATE_FUNCTION void diff --git a/src/main/lkt.c b/src/main/lkt.c index b673e2c5584abae578243267ad4ffcba0ac6deb1..267adffd9438113b22d7363b920f31d26fa019a9 100644 --- a/src/main/lkt.c +++ b/src/main/lkt.c @@ -4,13 +4,7 @@ #include <lektor/config.h> #include <lektor/segv.h> -#include <arpa/inet.h> -#include <sys/ioctl.h> #include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <sys/un.h> -#include <netdb.h> #include <signal.h> #define LKT_KEY_VALUE_SEP ": \n\t\0" @@ -49,11 +43,17 @@ static bool ___screen_detected = false; CONSTRUCTOR_FUNCTION setup_column_count(void) { + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) + ___column_count = (unsigned int)(csbi.dwSize.X); +#else struct winsize size; if (0 == ioctl(STDOUT_FILENO, TIOCGWINSZ, &size)) { ___screen_detected = true; ___column_count = size.ws_col; } + #endif } /* Row printer, should be queue/playlist/search agnostic, i.e. should handle @@ -220,12 +220,13 @@ lkt_get_query_type(struct cmd_args *args, char *const regex, size_t regex_len) } PRIVATE_FUNCTION int -read_socket(FILE *sock, char *buff, size_t max_len) +read_socket(SOCKET sock, char *buff, size_t max_len) { - size_t i, len = 0; + size_t i; + int len = 0; memset(buff, 0, max_len * sizeof(char)); for (i = 0; i < max_len - 1; ++i) { - len = fread(buff + i, sizeof(char), 1, sock); + len = recv(sock, buff+i, (int)max_len, 0); if (buff[i] == '\n' || len != 1) break; } @@ -234,23 +235,22 @@ read_socket(FILE *sock, char *buff, size_t max_len) } PRIVATE_FUNCTION EXIT_FUNCTION -exit_with_status(FILE *sock, char *buff) +exit_with_status(SOCKET sock, char *buff) { read_socket(sock, buff, 2); FAIL_IF(buff[0] != 'O' && buff[1] != 'K', "ACK"); exit(EXIT_SUCCESS); } -PRIVATE_FUNCTION FILE * +PRIVATE_FUNCTION SOCKET create_socket(const char *host_arg, const char *port_arg) { - FILE *socket_desc; - int cx; + SOCKET cx; int domain; struct sockaddr *ptr_sock; socklen_t sock_len; - /* Unix socket */ + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) if (STR_NMATCH(port_arg, "unix", 4)) { struct sockaddr_un sock; @@ -265,46 +265,45 @@ create_socket(const char *host_arg, const char *port_arg) /* TCP socket */ else { - struct addrinfo hints, *found; - struct sockaddr sock; + #endif + struct addrinfo hints, *found; + struct sockaddr sock; - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = 0; - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_flags = 0; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(host_arg, port_arg, &hints, &found) != 0 || (found == NULL)) - LOG_FATAL("getaddrinfo failed, this can be due to php " - "invocation of lkt or an invalid hostname..."); + if (getaddrinfo(host_arg, port_arg, &hints, &found) != 0 || (found == NULL)) + LOG_FATAL("getaddrinfo failed, this can be due to php " + "invocation of lkt or an invalid hostname..."); - sock = *found->ai_addr; - sock_len = found->ai_addrlen; - freeaddrinfo(found); + sock = *found->ai_addr; + sock_len = found->ai_addrlen; + freeaddrinfo(found); - ptr_sock = &sock; - domain = AF_INET; + ptr_sock = &sock; + domain = AF_INET; } /* Common part */ cx = socket(domain, SOCK_STREAM, 0); - FAIL_IF(cx <= 0 || connect(cx, ptr_sock, sock_len), + FAIL_IF(cx == INVALID_SOCKET || connect(cx, ptr_sock, sock_len), "Connect to socket failed, is lektord launched?"); - socket_desc = fdopen(cx, "r+"); - FAIL_IF(!socket_desc, "Failed to connect to lektord"); - return socket_desc; + return cx; } -PRIVATE_FUNCTION FILE * +PRIVATE_FUNCTION SOCKET lkt_connect(void) { char buff[LKT_MESSAGE_MAX]; - FILE *sock = create_socket(host, port); + SOCKET sock = create_socket(host, port); read_socket(sock, buff, LKT_MESSAGE_MAX); return sock; } PRIVATE_FUNCTION void -write_socket(FILE *sock, const char *format, ...) +write_socket(SOCKET sock, const char *format, ...) { char buff[LKT_MESSAGE_MAX]; va_list ap; @@ -335,7 +334,7 @@ lkt_skip_key(char *buffer) } PRIVATE_FUNCTION void -send_cmd_with_uri(FILE *sock, char *cmd, int argc, const char **argv) +send_cmd_with_uri(SOCKET sock, char *cmd, int argc, const char **argv) { char buf[LKT_MESSAGE_MAX]; struct cmd_args args = CMD_ARGS_FROM(argc, argv); @@ -351,7 +350,7 @@ send_cmd_with_uri(FILE *sock, char *cmd, int argc, const char **argv) PRIVATE_FUNCTION EXIT_FUNCTION func(struct cmd_args *args) \ { \ FAIL_IF(args->argc != 2, "Need two arguments"); \ - FILE *sock = lkt_connect(); \ + SOCKET sock = lkt_connect(); \ char buff[2]; \ write_socket(sock, cmd " %s %s\n", args->argv[0], args->argv[1]); \ exit_with_status(sock, buff); \ @@ -366,7 +365,7 @@ just_send_two_args(queue_swapid__, "swapid"); PRIVATE_FUNCTION EXIT_FUNCTION func(struct cmd_args *args) \ { \ FAIL_IF(args->argc != 1, "Invalid argument"); \ - FILE *sock = lkt_connect(); \ + SOCKET sock = lkt_connect(); \ char buff[2]; \ write_socket(sock, cmd " %s\n", args->argv[0]); \ exit_with_status(sock, buff); \ @@ -403,7 +402,7 @@ PRIVATE_FUNCTION EXIT_FUNCTION simple_send_with_password__(const char *cmd) { FAIL_UNLESS(pwd, "Password not provided"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, "command_list_begin\n"); write_socket(sock, "password %s\n", pwd); write_socket(sock, "%s\n", cmd); @@ -429,7 +428,7 @@ PRIVATE_FUNCTION EXIT_FUNCTION rescan_or_update__(struct cmd_args *args, const char *cmd) { FAIL_UNLESS(pwd, "Password not provided"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); /* All the db */ if (args->argc == 0) { @@ -476,7 +475,7 @@ queue_replace__(struct cmd_args *args) FAIL_IF(args->argc != 1, "Invalid argument"); char buff[LKT_MESSAGE_MAX]; bool play = false; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); FOR_EVER { @@ -493,7 +492,7 @@ queue_replace__(struct cmd_args *args) HANDLE_STATUS(buff, { break; }); } - fclose(sock); + closesocket(sock); sock = lkt_connect(); write_socket(sock, "command_list_begin\n"); write_socket(sock, "clear\n"); @@ -526,7 +525,7 @@ play__(struct cmd_args *args) static const char cmd_pause__[] = "pause\n"; char buff[LKT_MESSAGE_MAX]; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, status__); FOR_EVER @@ -536,7 +535,7 @@ play__(struct cmd_args *args) size_t len = strcspn(buff, LKT_KEY_VALUE_SEP); if (STR_NMATCH(buff, "state", len)) { - fclose(sock); + closesocket(sock); if (STR_NMATCH(lkt_skip_key(buff), "stop", 4)) { if (!pos) @@ -560,7 +559,7 @@ ping__(struct cmd_args *args) { FAIL_IF(args->argc != 0, "Invalid argument, the ping command takes no arguments"); char buff[6]; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); memset(buff, 0, sizeof(buff)); write_socket(sock, "ping\n"); read_socket(sock, buff, 6 * sizeof(char)); @@ -569,7 +568,7 @@ ping__(struct cmd_args *args) } PRIVATE_FUNCTION EXIT_FUNCTION -read_kara_and_exit(FILE *sock) +read_kara_and_exit(SOCKET sock) { char *mem = NULL; char buff[LKT_MESSAGE_MAX]; @@ -624,7 +623,7 @@ queue_id__(struct cmd_args *args) FAIL_IF(args->argc != 1, "Invalid argument, the current command takes one argument"); char probe_id__[LKT_LINE_MAX]; safe_snprintf(probe_id__, LKT_LINE_MAX, "playlistid %ld\n", strtol(args->argv[0], NULL, 0)); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, probe_id__); read_kara_and_exit(sock); } @@ -634,7 +633,7 @@ current__(struct cmd_args *args) { FAIL_IF(args->argc != 0, "Invalid argument, the current command takes no arguments"); static const char current_song__[] = "currentsong\n"; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, current_song__); read_kara_and_exit(sock); } @@ -645,7 +644,7 @@ queue_pop__(struct cmd_args *args) FAIL_IF(args->argc, "Invalid argument"); int song = 0; char buff[LKT_MESSAGE_MAX]; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); /* Get lektor's status. */ write_socket(sock, "status\n"); @@ -668,7 +667,7 @@ queue_pop__(struct cmd_args *args) #undef assign_int song += 1; /* Needs the +1, see status command */ - fclose(sock); + closesocket(sock); sock = lkt_connect(); if (!song) exit(EXIT_FAILURE); @@ -702,7 +701,7 @@ status__(struct cmd_args *args) size_t len; memset(flags, 0, 24 * sizeof(char)); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); #define assign_flag(str, f) \ if (STR_NMATCH(buff, str, len) && (atoi(lkt_skip_key(buff)) == 1)) { \ @@ -763,7 +762,7 @@ status__(struct cmd_args *args) } /* End of communication */ - fclose(sock); + closesocket(sock); #undef assign_flag #undef assign_int @@ -808,7 +807,7 @@ queue_remove__(struct cmd_args *args) static const char *cmd__ = "deleteid %d\n"; int dumy = 0; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); char buff[3]; sscanf(args->argv[0], "%d", &dumy); @@ -827,7 +826,7 @@ queue_delete__(struct cmd_args *args) static const char *cmd_id__ = "delete %d\n"; int dumy = 0; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); char buff[3]; sscanf(args->argv[0], "%d", &dumy); @@ -844,7 +843,7 @@ queue_add__(struct cmd_args *args) { char buff[3]; FAIL_IF(args->argc < 1, "Invalid arguments"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); send_cmd_with_uri(sock, "add", args->argc, args->argv); exit_with_status(sock, buff); } @@ -854,7 +853,7 @@ queue_insert__(struct cmd_args *args) { char buff[3]; FAIL_IF(args->argc < 1, "Invalid arguments"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); send_cmd_with_uri(sock, "__insert", args->argc, args->argv); exit_with_status(sock, buff); } @@ -871,7 +870,7 @@ queue_seek__(struct cmd_args *args) FAIL_IF(STRTOL_ERROR(id) || (endptr == args->argv[0]), "Invalid argument, not an integer"); FAIL_IF(*endptr != '\0', "Invalid argument, must be only one integer"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, "playid %ld\n", id); exit_with_status(sock, buf); } @@ -898,7 +897,7 @@ queue_pos__(struct cmd_args *args) up = atoi(endptr); } - FILE *sock = NULL; + SOCKET sock = INVALID_SOCKET; redo: sock = lkt_connect(); if (up != 0) @@ -914,7 +913,7 @@ redo: if (STR_NMATCH(buff, "continue:", strlen("continue:"))) { continuation = atoi(lkt_skip_key(buff)); if (continuation > 0) { - fclose(sock); + closesocket(sock); goto redo; } } @@ -946,7 +945,7 @@ queue_list__(struct cmd_args *args) /* Get the current pos to get limits for the playlist command. */ - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, "status\n"); #define assign_int(str, var) \ @@ -965,7 +964,7 @@ queue_list__(struct cmd_args *args) HANDLE_STATUS(buff, { break; }); } #undef assign_int - fclose(sock); + closesocket(sock); /* Get the content of the queue. */ @@ -990,7 +989,7 @@ plt_add__(struct cmd_args *args) struct cmd_args args_regex = CMD_ARGS_NEXT(*args); FAIL_IF(lkt_get_query_type(&args_regex, regex, LKT_MESSAGE_MAX), "Query is invalid"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, "playlistadd %s %s\n", args->argv[0], regex); exit_with_status(sock, buff); } @@ -998,7 +997,7 @@ plt_add__(struct cmd_args *args) PRIVATE_FUNCTION EXIT_FUNCTION plt_delete__(struct cmd_args *args) { - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); char buff[2]; char cmd[128]; FAIL_IF(args->argc < 3, "Invalid argument"); @@ -1012,7 +1011,7 @@ PRIVATE_FUNCTION EXIT_FUNCTION stickers_get__(struct cmd_args *args) { char buff[LKT_MESSAGE_MAX]; - FILE *sock; + SOCKET sock; if (args->argc == 2) write_socket(sock = lkt_connect(), "sticker get %s %s\n", args->argv[0], args->argv[1]); @@ -1045,7 +1044,7 @@ PRIVATE_FUNCTION EXIT_FUNCTION stickers_set__(struct cmd_args *args) { FAIL_IF(args->argc != 4, "Invalid argument"); - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); char buff[2]; write_socket(sock, "sticker set %s %s %s %s\n", args->argv[0], args->argv[1], args->argv[2], args->argv[3]); @@ -1055,7 +1054,7 @@ stickers_set__(struct cmd_args *args) PRIVATE_FUNCTION EXIT_FUNCTION stickers_delete__(struct cmd_args *args) { - FILE *sock; + SOCKET sock; char buff[2]; if (args->argc == 2) write_socket(sock = lkt_connect(), "sticker delete %s %s", args->argv[0], args->argv[1]); @@ -1074,7 +1073,7 @@ ___continuation_calls(const char *cmd) { char buff[LKT_MESSAGE_MAX]; int continuation = 0; - FILE *sock = NULL; + SOCKET sock = INVALID_SOCKET; redo: sock = lkt_connect(); @@ -1087,7 +1086,7 @@ redo: if (STR_NMATCH(buff, "continue:", strlen("continue:"))) { continuation = atoi(lkt_skip_key(buff)); - fclose(sock); + closesocket(sock); goto redo; } @@ -1125,7 +1124,7 @@ search_with_cmd__(struct cmd_args *args, const char *cmd) char buff[LKT_MESSAGE_MAX]; char regex[LKT_MESSAGE_MAX]; int continuation = 0; - FILE *sock = NULL; + SOCKET sock = INVALID_SOCKET; FAIL_IF(lkt_get_query_type(args, regex, LKT_MESSAGE_MAX), "Query is invalid"); @@ -1140,7 +1139,7 @@ redo: if (STR_NMATCH(buff, "continue:", strlen("continue:"))) { continuation = atoi(lkt_skip_key(buff)); - fclose(sock); + closesocket(sock); goto redo; } @@ -1156,7 +1155,7 @@ search_get__(struct cmd_args *args) FAIL_IF(!strtol(args->argv[0], NULL, 0), "Invalid id"); char buff[LKT_MESSAGE_MAX]; char UNUSED sink; - FILE *sock = lkt_connect(); + SOCKET sock = lkt_connect(); write_socket(sock, "find %s\n", args->argv[0]); FOR_EVER @@ -1179,7 +1178,7 @@ search_plt__(struct cmd_args *args) char buff[LKT_MESSAGE_MAX]; char regex[LKT_MESSAGE_MAX]; int continuation = 0; - FILE *sock = NULL; + SOCKET sock = INVALID_SOCKET; struct cmd_args args_regex = CMD_ARGS_NEXT(*args); FAIL_IF(args->argc < 2, "Invalid number of arguments"); @@ -1196,7 +1195,7 @@ redo: if (STR_NMATCH(buff, "continue:", strlen("continue:"))) { continuation = atoi(lkt_skip_key(buff)); - fclose(sock); + closesocket(sock); goto redo; } @@ -1377,11 +1376,17 @@ lkt_logfile_write(UNUSED struct lkt_logfile *logfile, UNUSED const char *line) int main(int argc, const char **argv) { + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + WSADATA WSAData; + WSAStartup(MAKEWORD(2,0), &WSAData); + #endif + lkt_segv_quiet(); lkt_install_segv_handler(); lkt_set_log_level(LOG_LEVEL_INFO); cmd_set_executable_name("lkt"); + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) /* Enforce some locals */ RETURN_UNLESS(setlocale(LC_ALL, ""), "Failed to set LC_ALL to UTF-8", 1); RETURN_UNLESS(setlocale(LC_CTYPE, ""), "Failed to set LC_CTYPE", 1); @@ -1390,6 +1395,7 @@ main(int argc, const char **argv) if (signal(SIGPIPE, sigpipe__)) LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)"); + #endif /* Parse */ cmd_parse_env(env_, &argc, &argv); diff --git a/src/main/luka.c b/src/main/luka.c index 43f20460d587e84f10023fdedd0b393745afb3d0..d88f0e2853de1025c4d5409e6319de1c9eb23362 100644 --- a/src/main/luka.c +++ b/src/main/luka.c @@ -456,6 +456,7 @@ main(const int argc, const char **argv) lkt_segv_quiet(); lkt_install_segv_handler(); + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) /* Enforce some locals */ RETURN_UNLESS(setlocale(LC_ALL, ""), "Failed to set LC_ALL to UTF-8", 1); RETURN_UNLESS(setlocale(LC_CTYPE, ""), "Failed to set LC_CTYPE", 1); @@ -464,6 +465,7 @@ main(const int argc, const char **argv) if (signal(SIGPIPE, __sigpipe)) LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)"); + #endif cmd_parse(__options, argc - 1, argv + 1); } diff --git a/src/main/server.c b/src/main/server.c index f795ff028d05dc65c3ac01c7c7e59df64b505c79..695552673f0aa7adfae64cb29bd51b6b9be3b8f0 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -9,11 +9,8 @@ #include <lektor/launch.h> #include <lektor/logfile.h> -#include <wait.h> -#include <spawn.h> #include <libgen.h> #include <signal.h> -#include <termios.h> #if defined(LKT_STATIC_MODULE) REG_DECLARE(sdl2_reg) @@ -32,6 +29,10 @@ main(int argc, char *argv[]) { lkt_install_segv_handler(); lkt_thread_set_name("lektord/daemon"); + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + WSADATA WSAData; + WSAStartup(MAKEWORD(2,0), &WSAData); + #endif REG_BEGIN(server_reg) REG_ADD(launch_ext_klkt) @@ -45,10 +46,12 @@ main(int argc, char *argv[]) REG_END() /* Enforce some locals */ + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) RETURN_UNLESS(setlocale(LC_ALL, ""), "Failed to set LC_ALL to UTF-8", 1); RETURN_UNLESS(setlocale(LC_CTYPE, ""), "Failed to set LC_CTYPE", 1); RETURN_UNLESS(setlocale(LC_NUMERIC, ""), "Failed to set LC_NUMERIC for mpv", 1); RETURN_UNLESS(STR_MATCH(nl_langinfo(CODESET), "UTF-8"), "Your locale is not set to an UTF-8 one. " "Consider using en_US.UTF-8 or fr_FR.UTF-8!", 1); + #endif int autoclear; int opt; @@ -155,5 +158,4 @@ main(int argc, char *argv[]) config_handle_hook(srv.db, "launched"); lkt_listen(&srv); LOG_FATAL("The lkt_listen function returned, it shouldn't happen"); - return EXIT_FAILURE; } diff --git a/src/mkv/write.c b/src/mkv/write.c index a4aafb82275d240a0b544322cd5ca9ffa1b8ba06..02cffc70839ea8b76b688cabb854aa998ab33588 100644 --- a/src/mkv/write.c +++ b/src/mkv/write.c @@ -2,8 +2,6 @@ #include <lektor/common.h> #include <lektor/mkv.h> -#include <dirent.h> -#include <sys/wait.h> #define METADATA_TEMPLATE \ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ @@ -48,6 +46,7 @@ static bool mkvpropedit__(const char *const args[]) { + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) pid_t pid; int wstatus, status, fd; @@ -94,6 +93,10 @@ mkvpropedit__(const char *const args[]) } return true; + #else + LOG_ERROR("MKV", "The call to mkvpropedit call is not implemented in windows"); + return false; + #endif } int diff --git a/src/module/module_repo.c b/src/module/module_repo.c index b44c82f2bfb8bae906e60589325d10ba66aca519..f57e3847ce9d5912d1d94bec85214d79838b67a8 100644 --- a/src/module/module_repo.c +++ b/src/module/module_repo.c @@ -275,11 +275,19 @@ err: PRIVATE_FUNCTION int ___download_kara(const char *url, const char *path, int override) { + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + static const int open_flags_1 = O_WRONLY | O_APPEND | O_CREAT | O_EXCL; + static const int open_flags_2 = O_WRONLY | O_CREAT; + #else + static const int open_flags_1 = O_WRONLY | O_APPEND | O_CREAT | O_EXCL | O_NOFOLLOW; + static const int open_flags_2 = O_WRONLY | O_CREAT | O_NOFOLLOW; + #endif + struct curl_slist *headers = NULL; CURL *curl_handle; CURLcode ret = 1; errno = 0; - int fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_EXCL | O_NOFOLLOW, S_IRUSR | S_IWUSR); + int fd = open(path, open_flags_1, S_IRUSR | S_IWUSR); retest: if (fd < 0) { @@ -295,7 +303,7 @@ retest: } override = false; - fd = open(path, O_WRONLY | O_CREAT | O_NOFOLLOW, S_IRUSR | S_IWUSR); + fd = open(path, open_flags_2, S_IRUSR | S_IWUSR); goto retest; } diff --git a/src/module/worker.c b/src/module/worker.c new file mode 100644 index 0000000000000000000000000000000000000000..bebd6c47af92e15a00da8aaea5a6f58f26f4baf0 --- /dev/null +++ b/src/module/worker.c @@ -0,0 +1,161 @@ +#include "worker.h" +#include <lektor/common.h> +//#include <sys/sysinfo.h> +#include <sched.h> + +#include <windows.h> + +static void * +___worker_thread(void *___pool) +{ + lkt_thread_set_name("lektord/worker"); + + volatile struct worker_pool *pool = (volatile struct worker_pool *)___pool; + volatile void *volatile arg; + worker_function func; + FOR_EVER + { + assert(!pthread_mutex_lock((pthread_mutex_t *)&pool->lock)); + if (pool->len) { + --(pool->len); + ++(pool->thread_working); + func = pool->functions[pool->len]; + arg = pool->args[pool->len]; + } else if (pool->exit) { + assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); + LOG_INFO("WORKER", "Exiting"); + break; + } else { + assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); + sleep(1); + continue; + } + + assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); + LOG_INFO("WORKER", "Picked up a function"); + func(___pool, (void *)arg); + LOG_INFO("WORKER", "Finished work for a function"); + + assert(!pthread_mutex_lock((pthread_mutex_t *)&pool->lock)); + --(pool->thread_working); + assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); + } + pthread_exit(NULL); + return NULL; +} + +WORKER_STATUS +worker_pool_get_status(void *__pool) +{ + volatile struct worker_pool *pool = (volatile struct worker_pool *)__pool; + assert(!pthread_mutex_lock((pthread_mutex_t *)&pool->lock)); + WORKER_STATUS ret = WORKER_STATUS_NONE; + + /* Case handling to get the correct status, simple for the moment, but may + * involve some logic in the future. */ + if (pool->exit && pool->len == 0) + ret = WORKER_STATUS_INTERRUPT; + + assert(!pthread_mutex_unlock((pthread_mutex_t *)&pool->lock)); + return ret; +} + +void +worker_pool_interrupt(struct worker_pool *pool) +{ + assert(!pthread_mutex_lock(&pool->lock)); + pool->len = 0; + pool->exit = 1; + assert(!pthread_mutex_unlock(&pool->lock)); +} + +int +worker_pool_new(struct worker_pool *ret, size_t init_size, size_t thread_count) +{ + if (!thread_count) { + //int nprocs = get_nprocs_conf(); + int nprocs = 2; + assert(nprocs > 0); + thread_count = (size_t)nprocs; + } + struct worker_pool __ret = { + .functions = LKT_ALLOC_ARRAY(worker_function, init_size), + .args = LKT_ALLOC_ARRAY(volatile void *, init_size), + .threads = LKT_ALLOC_ARRAY(pthread_t, thread_count), + .size = init_size, + .thread_size = thread_count, + .len = 0u, + .exit = 0, + }; + *ret = __ret; + assert(!pthread_mutex_init(&ret->lock, NULL)); + size_t i; + for (i = 0; i < ret->thread_size; ++i) + assert(!pthread_create(&ret->threads[i], NULL, ___worker_thread, ret)); + return 0; +} + +void +worker_pool_free(struct worker_pool *pool) +{ + LOG_DEBUG("WORKER", "Freeing worker pool %p", pool); + size_t i; + pool->exit = 1; + for (i = 0; i < pool->thread_size; ++i) + pthread_join(pool->threads[i], NULL); + assert(!pthread_mutex_lock(&pool->lock)); + + safe_free((void **)&pool->threads); + safe_free((void **)&pool->functions); + safe_free((void **)&pool->args); + pool->thread_size = 0u; + pool->size = 0u; + pool->len = 0u; + + assert(!pthread_mutex_unlock(&pool->lock)); +} + +int +worker_pool_push(struct worker_pool *pool, worker_function func, void *arg) +{ + int ret = 1; + assert(!pthread_mutex_lock(&pool->lock)); + if (pool->exit) { + LOG_ERROR("WORKER", "Can't push new jobs to worker if interupt was requested"); + goto error; + } + + if (pool->len == pool->size) { + if (pool->size < 1) + pool->size = 2; + size_t nsize = 2 * pool->size; + void *new_func = safe_realloc((void *)pool->functions, (long unsigned int)(nsize * sizeof(worker_function))); + void *new_args = safe_realloc((void *)pool->args, (long unsigned int)(nsize * sizeof(void *))); + + pool->size *= 2; + pool->functions = new_func; + pool->args = new_args; + } + + pool->functions[pool->len] = func; + pool->args[pool->len] = arg; + ++(pool->len); + ret = 0; +error: + assert(!pthread_mutex_unlock(&pool->lock)); + return ret; +} + +void +worker_pool_waitall(struct worker_pool *pool) +{ + /* No lock, nothing, just test and yield */ + FOR_EVER_IF (pool->len) + sched_yield(); +} + +size_t +worker_pool_get_working_count(struct worker_pool *pool) +{ + return pool->thread_working; +} diff --git a/src/net/listen.c b/src/net/listen.c index 700f73fbc4b34817d423879dbda0e96b7c8e7e79..dede5d96cd4cbf4a9c1f418e4ab10664d2bf91d5 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -7,13 +7,6 @@ #include <signal.h> #include <sched.h> -#include <netdb.h> -#include <poll.h> - -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/un.h> -#include <sys/socket.h> /* Server commands, stored in a trie for a bit more efficient lookups. * Commands have ascii names, but use the size of a char to not bother with @@ -416,7 +409,7 @@ handle_incoming_data(struct lkt_state *srv, size_t i) LKT_MESSAGE_MAX - cli->buffer_in_len, 0); if (n < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) + if (is_error_would_block(get_last_error())) return 0; return -1; } else if (n == 0) @@ -473,12 +466,13 @@ handle_outgoing_data(struct lkt_state *srv, size_t c) msg = cli->buffer_out[i]; n = lkt_message_send(srv->fds[c].fd, msg); if (n <= 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) { + const int error = get_last_error(); + if (is_error_would_block(error)) { cli->buffer_out_len -= i; memmove(cli->buffer_out, cli->buffer_out + i, cli->buffer_out_len); return 0; } - if (errno == EPIPE) { + if (is_error_broken_pipe(error)) { LOG_WARN("NETWORK", "Client %ld is out, free all its messages", c); handle_disconnected_client(srv, i); } @@ -494,21 +488,29 @@ handle_outgoing_data(struct lkt_state *srv, size_t c) return 0; } -typedef int (*init_socket_func)(const char *, const char *); +typedef SOCKET (*init_socket_func)(const char *, const char *); static void init_permission_socket_unix(const char *file, int perms) { errno = 0; - if (chmod(file, (__mode_t)perms) < 0) { + if (chmod(file, perms) < 0) { LOG_FATAL("INIT", "Failed to set '%s' to 0%o: %s", file, perms, strerror(errno)); } LOG_INFO("INIT", "Set socket '%s' to perms 0%o", file, perms); } static inline int -__set_socket_flags(int fd) +__set_socket_flags(SOCKET fd) { + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + u_long iMode = 1; + int err = ioctlsocket(fd, (long int)FIONBIO, &iMode); + if (err != 0){ + LOG_ERROR("INIT", "Failed to set socket flag: %s", strerror(errno)); + goto failure; + } + #else int flags = fcntl(fd, F_GETFL, 0); if (flags < 0) { LOG_ERROR("INIT", "Failed to get socket flag: %s", strerror(errno)); @@ -519,6 +521,7 @@ __set_socket_flags(int fd) LOG_ERROR("INIT", "Failed to set non-blocking flag: %s", strerror(errno)); goto failure; } + #endif return 0; failure: @@ -526,8 +529,9 @@ failure: } static int -init_listening_socket_unix(const char *file, const char UNUSED *type /* == "unix" */) +init_listening_socket_unix(const char UNUSED *file, const char UNUSED *type /* == "unix" */) { + #if defined(LKT_OS_TOASTER) && (LKT_OS_TOASTER == 1) if (!STR_NMATCH(type, "unix", 4)) LOG_FATAL("Incorrect call to the function, 'port' is not set to 'unix'"); @@ -538,7 +542,7 @@ init_listening_socket_unix(const char *file, const char UNUSED *type /* == "unix LOG_DEBUG("INIT", "Unlink of socket target file %s failed: %s", file, strerror(errno)); } - int fd = socket(AF_UNIX, SOCK_STREAM, 0); + SOCKET fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { LOG_ERROR("INIT", "Failed to create unix socket %s: %s", file, strerror(errno)); goto failure; @@ -565,36 +569,39 @@ init_listening_socket_unix(const char *file, const char UNUSED *type /* == "unix } return fd; + #else + goto failure; + #endif failure: close(fd); return -1; } -static int +static SOCKET init_listening_socket_net(const char *host, const char *port) { - errno = 0; - int fd = -1; - static const int yes = 1; - struct addrinfo *available; + errno = 0; + static const char yes = 1; + SOCKET fd = INVALID_SOCKET; struct addrinfo hints = { 0 }; + struct addrinfo *available = NULL; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if (getaddrinfo(host, port, &hints, &available) < 0) { LOG_ERROR("INIT", "getaddrinfo failed: %s", strerror(errno)); - return -1; + return INVALID_SOCKET; } for (struct addrinfo *p = available; p; p = p->ai_next) { fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if (fd < 0) { + if (fd == INVALID_SOCKET) { LOG_ERROR("INIT", "Failed to create tcp socket: %s", strerror(errno)); continue; } - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0) { LOG_ERROR("INIT", "Failed to reuse address: %s", strerror(errno)); goto failure; } @@ -604,8 +611,8 @@ init_listening_socket_net(const char *host, const char *port) goto failure; } - if (bind(fd, p->ai_addr, p->ai_addrlen) < 0) { - close(fd); + if (bind(fd, p->ai_addr, (int)(p->ai_addrlen)) != 0) { + closesocket(fd); LOG_ERROR("INIT", "Failed to bind tcp socket: %s", strerror(errno)); continue; } @@ -613,21 +620,21 @@ init_listening_socket_net(const char *host, const char *port) break; failure: - close(fd); - fd = -1; + closesocket(fd); + fd = INVALID_SOCKET; break; } freeaddrinfo(available); - if (fd < 0) { + if (fd == INVALID_SOCKET) { LOG_ERROR("NETWORK", "Failed to bind to %s:%s", host ? host : "0.0.0.0", port); - return -1; + return INVALID_SOCKET; } if (listen(fd, LKT_BACKLOG) < 0) { LOG_ERROR("NETWORK", "Failed to listen: %s", strerror(errno)); - return -1; + return INVALID_SOCKET; } LOG_INFO("NETWORK", "Listening on %s:%s", host ? host : "0.0.0.0", port); @@ -635,19 +642,20 @@ init_listening_socket_net(const char *host, const char *port) } static int -accept_all(int listen_fd, struct pollfd *fds, size_t fds_max, size_t *fds_len) +accept_all(SOCKET listen_fd, struct pollfd* fds, ULONG fds_max, ULONG *fds_len) { + SOCKET fd; struct sockaddr_in peer_addr; socklen_t pa_size = sizeof(peer_addr); - int fd; fds += *fds_len; for (int n = 0;; n++) { fd = accept(listen_fd, (struct sockaddr *)&peer_addr, &pa_size); - if (fd < 0) { - if (errno == EWOULDBLOCK || errno == EAGAIN) + if (fd == INVALID_SOCKET) { + const int error = get_last_error(); + if (is_error_would_block(error)) return n; - if (errno == ECONNABORTED) + id (is_error_connection_aborted(error)) continue; perror("accept"); return -1; @@ -658,6 +666,16 @@ accept_all(int listen_fd, struct pollfd *fds, size_t fds_max, size_t *fds_len) break; } + + #if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + u_long iMode = 1; + int err = ioctlsocket(fd, (long int)FIONBIO, &iMode); + if (err != 0){ + perror("fcntl"); + break; + } + #else + int flag = fcntl(fd, F_GETFL, 0); const int flag = fcntl(fd, F_GETFL, 0); if (flag < 0) { perror("fcntl"); @@ -667,25 +685,27 @@ accept_all(int listen_fd, struct pollfd *fds, size_t fds_max, size_t *fds_len) perror("fcntl"); break; } + #endif const char *host = inet_ntoa(peer_addr.sin_addr); const uint16_t port = htons(peer_addr.sin_port); LOG_INFO("NETWORK", "New connection from %s:%d", host, port); - fds->fd = fd; + fds->fd = fd; fds->events = POLLIN; fds++; (*fds_len)++; } shutdown(fd, SHUT_RDWR); - close(fd); + closesocket(fd); return -1; } static int handle_network_events(struct lkt_state *srv) { + errno = 0; const int n = poll(srv->fds, srv->fds_len, 100); if (n < 0 && errno != EAGAIN && errno != EINTR) { perror("poll failed"); @@ -709,12 +729,12 @@ handle_network_events(struct lkt_state *srv) msg = NULL; } - for (size_t i = 1; i < srv->fds_len; i++) { + for (size_t i = 1; i <= srv->fds_len; i++) { if (!srv->fds[i].revents) continue; if (srv->fds[i].revents & (POLLHUP | POLLERR)) { - close(srv->fds[i].fd); - srv->fds[i].fd = -1; + closesocket(srv->fds[i].fd); + srv->fds[i].fd = INVALID_SOCKET; srv->fds[i].revents &= ~(POLLHUP | POLLERR); handle_disconnected_client(srv, i); LOG_WARN("NETWORK", "Client %ld is out", i); @@ -722,20 +742,20 @@ handle_network_events(struct lkt_state *srv) } if (srv->fds[i].revents & POLLIN) { if (handle_incoming_data(srv, i) < 0) { - close(srv->fds[i].fd); - srv->fds[i].fd = -1; + closesocket(srv->fds[i].fd); + srv->fds[i].fd = INVALID_SOCKET; } } if (srv->fds[i].revents & POLLOUT) { if (handle_outgoing_data(srv, i) < 0) { - close(srv->fds[i].fd); - srv->fds[i].fd = -1; + closesocket(srv->fds[i].fd); + srv->fds[i].fd = INVALID_SOCKET; } } if (srv->clients[i - 1].request_close) { handle_outgoing_data(srv, i); - close(srv->fds[i].fd); - srv->fds[i].fd = -1; + closesocket(srv->fds[i].fd); + srv->fds[i].fd = INVALID_SOCKET; handle_disconnected_client(srv, i); } } @@ -856,8 +876,8 @@ void lkt_close_server(struct lkt_state *srv) { for (size_t i = 1; i <= srv->fds_len; ++i) { - close(srv->fds[i].fd); - srv->fds[i].fd = -1; + closesocket(srv->fds[i].fd); + srv->fds[i].fd = INVALID_SOCKET; srv->fds[i].revents &= ~(POLLHUP | POLLERR); handle_disconnected_client(srv, i); } @@ -1009,10 +1029,11 @@ ___lkt_handle_INT(struct lkt_state *srv) * it crashed. */ LOG_INFO("SIGNAL", "Now use default handler for SIGINT and SIGQUIT"); signal(SIGINT, SIG_DFL); +#if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) signal(SIGQUIT, SIG_DFL); +#endif lkt_close_server(srv); - exit(EXIT_SUCCESS); } @@ -1050,9 +1071,11 @@ handle_signals(struct lkt_state *srv) HANDLE(srv, INT) HANDLE(srv, ILL) + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) HANDLE(srv, QUIT) HANDLE(srv, USR1) HANDLE(srv, USR2) + #endif #undef HANDLE } @@ -1070,7 +1093,7 @@ lkt_listen(struct lkt_state *srv) if (fds_max_config <= 0) LOG_FATAL("The max_clients number must be a positive integer"); - srv->fds_max = (size_t)fds_max_config; + srv->fds_max = (ULONG)fds_max_config; srv->fds = LKT_ALLOC_STRUCT_ARRAY(pollfd, srv->fds_max); srv->clients = LKT_ALLOC_STRUCT_ARRAY(lkt_client, srv->fds_max); @@ -1082,9 +1105,11 @@ lkt_listen(struct lkt_state *srv) srv->___signal_ILL = ___lkt_handle_ILL; signal(SIGINT, ___signal_handler); signal(SIGILL, ___signal_handler); + #if !(defined(LKT_OS_WIN) && (LKT_OS_WIN == 1)) signal(SIGUSR1, ___signal_handler); signal(SIGUSR2, ___signal_handler); signal(SIGQUIT, ___signal_handler); + #endif LOG_INFO("INIT", "Signal handlers registered"); int is_unix_socket = STR_NMATCH(srv->port, "unix", 4); @@ -1105,10 +1130,10 @@ lkt_listen(struct lkt_state *srv) } } - init_socket_func init_sock = - is_unix_socket ? init_listening_socket_unix : init_listening_socket_net; + init_socket_func init_sock = init_listening_socket_net; + (void)init_listening_socket_unix; - if ((srv->fds[0].fd = init_sock(srv->host, srv->port)) < 0) + if ((srv->fds[0].fd = init_sock(srv->host, srv->port)) == INVALID_SOCKET) LOG_FATAL("Failed to init socket: %s:%s", srv->host, srv->port); if (is_unix_socket) init_permission_socket_unix(srv->host, perms); diff --git a/src/net/message.c b/src/net/message.c index 765f6fd8a4416e7354a0352f853b8ff0e393d683..9e5ee0ffffb2b8784ecd700613666481d0e206d5 100644 --- a/src/net/message.c +++ b/src/net/message.c @@ -55,7 +55,11 @@ lkt_message_clone(struct lkt_message *const msg) } int -lkt_message_send(int fd, const struct lkt_message *const msg) +lkt_message_send(SOCKET fd, const struct lkt_message *const msg) { +#if defined(LKT_OS_WIN) && (LKT_OS_WIN == 1) + return (int)send(fd, msg->data, (int)(msg->data_len), 0); +#else return (int)send(fd, msg->data, msg->data_len, MSG_NOSIGNAL); +#endif }