From ed3920e3cfd0ce54f549beed90e3951f380907e4 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Wed, 6 Oct 2010 11:15:09 +0200 Subject: [PATCH] Fix a rare bug in StartDaemonChild and GenericMain I've seen cases where the result from str(sys.exc_info()[1]) is ""; this breaks the error reporting as the parent relies on non-empty error messages to properly detect child status (otherwise it will try to read the pid and fail, so on). While this was always in case of asserts, we need to ensure this doesn't happen. Therefore we abstract this functionality (writing the error message) and ensure we write a non-empty string in the new function. Signed-off-by: Iustin Pop <iustin@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> --- lib/daemon.py | 3 +-- lib/utils.py | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/daemon.py b/lib/daemon.py index 302097a19..c3c476178 100644 --- a/lib/daemon.py +++ b/lib/daemon.py @@ -671,8 +671,7 @@ def GenericMain(daemon_name, optionparser, prep_results = None logging.info("%s daemon startup", daemon_name) except Exception, err: - if wpipe is not None: - os.write(wpipe, _BeautifyError(err)) + utils.WriteErrorToFD(wpipe, _BeautifyError(err)) raise if wpipe is not None: diff --git a/lib/utils.py b/lib/utils.py index 54588cf89..095e38b65 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -435,9 +435,7 @@ def _StartDaemonChild(errpipe_read, errpipe_write, except: # pylint: disable-msg=W0702 try: # Report errors to original process - buf = str(sys.exc_info()[1]) - - RetryOnSignal(os.write, errpipe_write, buf) + WriteErrorToFD(errpipe_write, str(sys.exc_info()[1])) except: # pylint: disable-msg=W0702 # Ignore errors in error handling pass @@ -445,6 +443,23 @@ def _StartDaemonChild(errpipe_read, errpipe_write, os._exit(1) # pylint: disable-msg=W0212 +def WriteErrorToFD(fd, err): + """Possibly write an error message to a fd. + + @type fd: None or int (file descriptor) + @param fd: if not None, the error will be written to this fd + @param err: string, the error message + + """ + if fd is None: + return + + if not err: + err = "<unknown error>" + + RetryOnSignal(os.write, fd, err) + + def _RunCmdPipe(cmd, env, via_shell, cwd, interactive): """Run a command and return its output. -- GitLab