diff --git a/bin/nntp-tiny-server b/bin/nntp-tiny-server index 590f8e5..0f394ae 100755 --- a/bin/nntp-tiny-server +++ b/bin/nntp-tiny-server @@ -6,6 +6,7 @@ import argparse from nntp.tiny.config import Config from nntp.tiny.db import Database from nntp.tiny.server import Server +from nntp.tiny.daemon import Daemon parser = argparse.ArgumentParser(description='Tiny NNTP server') parser.add_argument('--daemon', '-d', action='store_true', help='Run NNTP server as daemon in background') @@ -16,9 +17,6 @@ config = Config.load() server = Server(config) if args.daemon: - pid = os.fork() - - if pid > 0: - exit(0) + Daemon.init(config) server.run() diff --git a/lib/nntp/tiny/config.py b/lib/nntp/tiny/config.py index ba27afd..5058252 100644 --- a/lib/nntp/tiny/config.py +++ b/lib/nntp/tiny/config.py @@ -4,11 +4,35 @@ import configparser from typing import Optional class ConfigException(Exception): - def __init__(self, path: str): - self.path = path + pass + +class ConfigSectionException(ConfigException): + def __init__(self, section: str): + self.section = section def __str__(self): - return "Unable to locate file '" + self.path + "'" + return "Missing configuration section '%s'" % ( + self.section + ) + +class ConfigValueException(ConfigException): + def __init__(self, section: str, value: str): + self.section = section + self.value = value + + def __str__(self): + return "Missing configuration value '%s' in section '%s'" % ( + self.value, self.section + ) + +class ConfigFileException(ConfigException): + def __init__(self, paths: list): + self.paths = paths + + def __str__(self): + return "Unable to locate configuration file in: %s" % ( + ", ".join(self.paths) + ) class Config(): SEARCH_PATHS = [ @@ -29,7 +53,7 @@ class Config(): path = Config.find() if path is None: - raise ConfigException(path) + raise ConfigFileException(Config.SEARCH_PATHS) parser = configparser.ConfigParser() parser.read(path) diff --git a/lib/nntp/tiny/daemon.py b/lib/nntp/tiny/daemon.py new file mode 100644 index 0000000..72b7c07 --- /dev/null +++ b/lib/nntp/tiny/daemon.py @@ -0,0 +1,26 @@ +import os +import signal +import configparser + +from nntp.tiny.config import (ConfigSectionException, + ConfigValueException) + +class Daemon(): + def init(config: configparser.ConfigParser): + if not config.has_section('daemon'): + raise ConfigSectionException('daemon') + + if not config.has_option('daemon', 'pidfile'): + raise ConfigValueException('daemon', 'pidfile') + + pidfile = config.get('daemon', 'pidfile') + + pid = os.fork() + + if pid > 0: + exit(0) + + with open(pidfile, 'w') as fh: + print(str(os.getpid()), file=fh) + + signal.signal(signal.SIGTERM, lambda s, f: os.unlink(pidfile))