diff options
author | ToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp> | 2020-03-30 09:24:26 +0900 |
---|---|---|
committer | ToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp> | 2020-03-30 09:24:26 +0900 |
commit | 5b80bfd7bffd4c20d80b7c70a7130529e9a755dd (patch) | |
tree | b4bb18dcd1487dbf1ea8127e5671b7bb2eded033 /external/poky/bitbake/lib/bb/daemonize.py | |
parent | 706ad73eb02caf8532deaf5d38995bd258725cb8 (diff) |
agl-basesystem
Diffstat (limited to 'external/poky/bitbake/lib/bb/daemonize.py')
-rw-r--r-- | external/poky/bitbake/lib/bb/daemonize.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/external/poky/bitbake/lib/bb/daemonize.py b/external/poky/bitbake/lib/bb/daemonize.py new file mode 100644 index 00000000..c937675e --- /dev/null +++ b/external/poky/bitbake/lib/bb/daemonize.py @@ -0,0 +1,93 @@ +""" +Python Daemonizing helper + +Originally based on code Copyright (C) 2005 Chad J. Schroeder but now heavily modified +to allow a function to be daemonized and return for bitbake use by Richard Purdie +""" + +import os +import sys +import io +import traceback + +def createDaemon(function, logfile): + """ + Detach a process from the controlling terminal and run it in the + background as a daemon, returning control to the caller. + """ + + # Ensure stdout/stderror are flushed before forking to avoid duplicate output + sys.stdout.flush() + sys.stderr.flush() + + try: + # Fork a child process so the parent can exit. This returns control to + # the command-line or shell. It also guarantees that the child will not + # be a process group leader, since the child receives a new process ID + # and inherits the parent's process group ID. This step is required + # to insure that the next call to os.setsid is successful. + pid = os.fork() + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid == 0): # The first child. + # To become the session leader of this new session and the process group + # leader of the new process group, we call os.setsid(). The process is + # also guaranteed not to have a controlling terminal. + os.setsid() + try: + # Fork a second child and exit immediately to prevent zombies. This + # causes the second child process to be orphaned, making the init + # process responsible for its cleanup. And, since the first child is + # a session leader without a controlling terminal, it's possible for + # it to acquire one by opening a terminal in the future (System V- + # based systems). This second fork guarantees that the child is no + # longer a session leader, preventing the daemon from ever acquiring + # a controlling terminal. + pid = os.fork() # Fork a second child. + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if (pid != 0): + # Parent (the first child) of the second child. + # exit() or _exit()? + # _exit is like exit(), but it doesn't call any functions registered + # with atexit (and on_exit) or any registered signal handlers. It also + # closes any open file descriptors, but doesn't flush any buffered output. + # Using exit() may cause all any temporary files to be unexpectedly + # removed. It's therefore recommended that child branches of a fork() + # and the parent branch(es) of a daemon use _exit(). + os._exit(0) + else: + os.waitpid(pid, 0) + return + + # The second child. + + # Replace standard fds with our own + with open('/dev/null', 'r') as si: + os.dup2(si.fileno(), sys.stdin.fileno()) + + try: + so = open(logfile, 'a+') + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(so.fileno(), sys.stderr.fileno()) + except io.UnsupportedOperation: + sys.stdout = open(logfile, 'a+') + + # Have stdout and stderr be the same so log output matches chronologically + # and there aren't two seperate buffers + sys.stderr = sys.stdout + + try: + function() + except Exception as e: + traceback.print_exc() + finally: + bb.event.print_ui_queue() + # os._exit() doesn't flush open files like os.exit() does. Manually flush + # stdout and stderr so that any logging output will be seen, particularly + # exception tracebacks. + sys.stdout.flush() + sys.stderr.flush() + os._exit(0) |