diff --git a/.gitignore b/.gitignore index 567609b..6654b8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build/ +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 3841672..3c8a6b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,4 +9,4 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) add_subdirectory(common) add_subdirectory(server) -# add_subdirectory(client) +add_subdirectory(client) diff --git a/TODO.gmi b/TODO.gmi index b144e38..5ad4002 100644 --- a/TODO.gmi +++ b/TODO.gmi @@ -2,11 +2,12 @@ A list of things I'd like to accomplish ## In Progress -* Daemonise the serverside * Expose a socket or pipe on the daemon for the client * Create client to connect to daemon ## Completed +* Daemonise the serverside +* Parse command line arguments * Split into client, server, and common library * Write Makefile to automate compilation diff --git a/build.sh b/build.sh index d523c5b..0c2d9ad 100755 --- a/build.sh +++ b/build.sh @@ -20,7 +20,7 @@ cmake .. make if [ ${run_exe} -eq 1 ]; then - ./server/simworld-daemon + ./server/simworld-daemon "$@" fi cd .. diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..0a657a1 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,12 @@ +# client/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) +project(simworld-client VERSION 0.0.1 LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/client/src) +file(GLOB_RECURSE SOURCES ${SOURCE_DIR}/*.c) + +add_executable(${PROJECT_NAME} ${SOURCES}) +target_link_libraries(${PROJECT_NAME} PRIVATE simworld) + +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/common/include) diff --git a/client/src/main.c b/client/src/main.c new file mode 100644 index 0000000..6052ea9 --- /dev/null +++ b/client/src/main.c @@ -0,0 +1,8 @@ +// main.c + +#include + +int main(void) { + + return EXIT_SUCCESS; +} diff --git a/server/src/render/render.c b/client/src/render/render.c similarity index 100% rename from server/src/render/render.c rename to client/src/render/render.c diff --git a/server/src/render/render.h b/client/src/render/render.h similarity index 100% rename from server/src/render/render.h rename to client/src/render/render.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 79641a9..e151cc1 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -13,5 +13,4 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(LUA REQUIRED lua) target_link_libraries(${PROJECT_NAME} ${LUA_LIBRARIES}) - target_include_directories(${PROJECT_NAME} PRIVATE ${LUA_INCLUDE_DIRS}) diff --git a/common/include/error.h b/common/include/error.h index bf9ee1f..4ea7b9d 100644 --- a/common/include/error.h +++ b/common/include/error.h @@ -6,6 +6,8 @@ enum error_t { ERR_INPUT, ERR_ALLOC, ERR_NOTFOUND, + ERR_FORK, + ERR_SETSID, __ERR_COUNT, }; diff --git a/common/src/error.c b/common/src/error.c index 864dae0..893bc4a 100644 --- a/common/src/error.c +++ b/common/src/error.c @@ -7,6 +7,8 @@ char const *const ERROR_STRS[] = { "BAD INPUT", "ALLOCATION", "NOT FOUND", + "FORK", + "SETSID", }; _Static_assert( diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 0b7076f..3bb5250 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -6,5 +6,6 @@ project(simworld-daemon VERSION 0.0.1 LANGUAGES C) set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/server/src) file(GLOB_RECURSE SOURCES ${SOURCE_DIR}/*.c) -add_executable(simworld-daemon ${SOURCES}) +add_executable(${PROJECT_NAME} ${SOURCES}) + target_link_libraries(${PROJECT_NAME} PRIVATE simworld) diff --git a/server/src/daemon.c b/server/src/daemon.c new file mode 100644 index 0000000..356d745 --- /dev/null +++ b/server/src/daemon.c @@ -0,0 +1,32 @@ +// daemon.c + +#include "daemon.h" +#include +#include +#include +#include +#include +#include + +enum error_t daemonise(void) { + pid_t pid = fork(); + if (pid < 0) return ERR_FORK; // return if error + if (pid > 0) exit(EXIT_SUCCESS); // terminate parent + + if (setsid() < 0) return ERR_SETSID; + + // TODO: signal handling + signal(SIGCHLD, SIG_IGN); + signal(SIGHUP, SIG_IGN); + + pid = fork(); + if (pid < 0) return ERR_FORK; + if (pid > 0) exit(EXIT_SUCCESS); + + umask(0); + chdir("/"); + + for (int i = sysconf(_SC_OPEN_MAX); i >= 0; i++) close(i); + + return ERR_OK; +} diff --git a/server/src/daemon.h b/server/src/daemon.h new file mode 100644 index 0000000..2fbe159 --- /dev/null +++ b/server/src/daemon.h @@ -0,0 +1,8 @@ +#ifndef DAEMON_H +#define DAEMON_H + +#include "error.h" + +enum error_t daemonise(void); + +#endif diff --git a/server/src/main.c b/server/src/main.c index c72b73b..ced09dc 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -1,31 +1,66 @@ // main.c #include +#include +#include +#include +#include -#include "world.h" -#include "render/render.h" +#include -int main(void) { +#include "error.h" +#include "daemon.h" + +struct options_t { + bool daemonise; +}; + +enum error_t parse_arguments(struct options_t *options, int argc, char **argv) { + static struct option long_options[] = { + { "daemon", no_argument, 0, 'd' }, + { 0, 0, 0, 0 }, + }; + + while (true) { + int option_index = 0; + + int c = getopt_long(argc, argv, "d", long_options, &option_index); + + if (c == -1) break; + + switch (c) { + case 'd': + options->daemonise = true; + break; + + default: + return ERR_INPUT; + } + } + + return ERR_OK; +} + +int main(int argc, char **argv) { enum error_t err = ERR_OK; - struct world_t world; - err = world_init(&world, 10, 10); - if (err != ERR_OK) goto error; + struct options_t options = { false }; + err = parse_arguments(&options, argc, argv); + if (err) goto handle_error; - err = world_register_entity(&world, "john", 'j'); - if (err != ERR_OK) goto error_free; + if (options.daemonise) { + err = daemonise(); + if (err) goto handle_error; - err = world_place_entity(&world, 1, 1, 2); - if (err != ERR_OK) goto error_free; + openlog(NULL, LOG_PID, LOG_DAEMON); + syslog(LOG_NOTICE, "Daemon initialised"); + } - render_world(&world); - world_free(&world); - return 0; + if (options.daemonise) closelog(); + return EXIT_SUCCESS; -error_free: - world_free(&world); -error: - printf("ERROR: %s", ERROR_STRS[err]); - exit(err); +handle_error: + printf("ERROR: %s\n", ERROR_STRS[err]); + return err; }