From b9a66244f04e12509271feadf5d30d7bce2e81c9 Mon Sep 17 00:00:00 2001 From: James Lu Date: Fri, 30 Mar 2018 23:23:10 -0700 Subject: [PATCH] launcher: daemonize and write PID file only after reading control options (-s/-R/-r) --- launcher.py | 69 ++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/launcher.py b/launcher.py index 3050bc0..d68c556 100644 --- a/launcher.py +++ b/launcher.py @@ -46,37 +46,6 @@ def main(): from pylinkirc.log import log from pylinkirc import classes, utils, coremods - world.daemon = args.daemonize - if args.daemonize: - if args.no_pid: - print('ERROR: Combining --no-pid and --daemonize is not supported.') - sys.exit(1) - elif os.name != 'posix': - print('ERROR: Daemonization is not supported outside POSIX systems.') - sys.exit(1) - else: - log.info('Forking into the background.') - log.removeHandler(world.console_handler) - - # Adapted from https://stackoverflow.com/questions/5975124/ - if os.fork(): - # Fork and exit the parent process. - os._exit(0) - - os.setsid() # Decouple from our lovely terminal - if os.fork(): - # Fork again to prevent starting zombie apocalypses. - os._exit(0) - else: - # For foreground sessions, set the terminal window title. - # See https://bbs.archlinux.org/viewtopic.php?id=85567 & - # https://stackoverflow.com/questions/7387276/ - if os.name == 'nt': - import ctypes - ctypes.windll.kernel32.SetConsoleTitleW("PyLink %s" % __version__) - elif os.name == 'posix': - sys.stdout.write("\x1b]2;PyLink %s\x07" % __version__) - # Write and check for an existing PID file unless specifically told not to. if not args.no_pid: pidfile = '%s.pid' % conf.confname @@ -126,6 +95,7 @@ def main(): log.error("Alternatively, you can install psutil for Python 3 (pip3 install psutil), " "which will allow this launcher to detect stale PID files and ignore them.") sys.exit(1) + elif args.stop or args.restart or args.rehash: # XXX: also repetitive # --stop and --restart should take care of stale PIDs. if pid: @@ -135,12 +105,45 @@ def main(): log.error('Cannot stop/rehash PyLink: PID file %r does not exist.', pidfile) sys.exit(1) - with open(pidfile, 'w') as f: - f.write(str(os.getpid())) world._should_remove_pid = True log.info('PyLink %s starting...', __version__) + world.daemon = args.daemonize + if args.daemonize: + if args.no_pid: + print('ERROR: Combining --no-pid and --daemonize is not supported.') + sys.exit(1) + elif os.name != 'posix': + print('ERROR: Daemonization is not supported outside POSIX systems.') + sys.exit(1) + else: + log.info('Forking into the background.') + log.removeHandler(world.console_handler) + + # Adapted from https://stackoverflow.com/questions/5975124/ + if os.fork(): + # Fork and exit the parent process. + os._exit(0) + + os.setsid() # Decouple from our lovely terminal + if os.fork(): + # Fork again to prevent starting zombie apocalypses. + os._exit(0) + else: + # For foreground sessions, set the terminal window title. + # See https://bbs.archlinux.org/viewtopic.php?id=85567 & + # https://stackoverflow.com/questions/7387276/ + if os.name == 'nt': + import ctypes + ctypes.windll.kernel32.SetConsoleTitleW("PyLink %s" % __version__) + elif os.name == 'posix': + sys.stdout.write("\x1b]2;PyLink %s\x07" % __version__) + + # Write the PID file only after forking. + with open(pidfile, 'w') as f: + f.write(str(os.getpid())) + # Load configured plugins to_load = conf.conf['plugins'] utils.resetModuleDirs()