we do a lil daemonisation >:-)

This commit is contained in:
snit 2024-10-04 00:05:43 -05:00
parent 391db5c444
commit 174ed1ed30
15 changed files with 124 additions and 23 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build/
compile_commands.json

View File

@ -9,4 +9,4 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(common)
add_subdirectory(server)
# add_subdirectory(client)
add_subdirectory(client)

View File

@ -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

View File

@ -20,7 +20,7 @@ cmake ..
make
if [ ${run_exe} -eq 1 ]; then
./server/simworld-daemon
./server/simworld-daemon "$@"
fi
cd ..

12
client/CMakeLists.txt Normal file
View File

@ -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)

8
client/src/main.c Normal file
View File

@ -0,0 +1,8 @@
// main.c
#include <stdlib.h>
int main(void) {
return EXIT_SUCCESS;
}

View File

@ -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})

View File

@ -6,6 +6,8 @@ enum error_t {
ERR_INPUT,
ERR_ALLOC,
ERR_NOTFOUND,
ERR_FORK,
ERR_SETSID,
__ERR_COUNT,
};

View File

@ -7,6 +7,8 @@ char const *const ERROR_STRS[] = {
"BAD INPUT",
"ALLOCATION",
"NOT FOUND",
"FORK",
"SETSID",
};
_Static_assert(

View File

@ -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)

32
server/src/daemon.c Normal file
View File

@ -0,0 +1,32 @@
// daemon.c
#include "daemon.h"
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
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;
}

8
server/src/daemon.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef DAEMON_H
#define DAEMON_H
#include "error.h"
enum error_t daemonise(void);
#endif

View File

@ -1,31 +1,66 @@
// main.c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/syslog.h>
#include <unistd.h>
#include "world.h"
#include "render/render.h"
#include <getopt.h>
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;
render_world(&world);
world_free(&world);
return 0;
error_free:
world_free(&world);
error:
printf("ERROR: %s", ERROR_STRS[err]);
exit(err);
openlog(NULL, LOG_PID, LOG_DAEMON);
syslog(LOG_NOTICE, "Daemon initialised");
}
if (options.daemonise) closelog();
return EXIT_SUCCESS;
handle_error:
printf("ERROR: %s\n", ERROR_STRS[err]);
return err;
}