From 36496b91740b2af0099dce6066722f763b38341f Mon Sep 17 00:00:00 2001 From: George Hartzell Date: Thu, 3 Aug 2017 10:33:16 -0700 Subject: Fix crashes when running spack install under nohup (#4926) * Fix crashes when running spack install under nohup Fixes #4919 For reasons that I do not entire understand, duplicate_stream() throws an '[Errno 22] Invalid argument' exception when it tries to `os.fdopen()` the duplicated file descriptor generated by `os.dup(original.fileno())`. See spack/llnl/util/lang.py, line 394-ish. This happens when run under `nohup`, which supposedly has hooked `stdin` to `/dev/null`. It seems like opening and using `devnull` on the `input_stream` in this situation is a reasonable way to handle the problem. * Be more specific about error being handled. Only catch the specific error that happens when trying to dup the stdin that nohup provides. Catching e as a StandardErorr and then `type(e).__name__` tells me that it's an OSError. Printing e.errno tells me that it's 22 Double checking tells me that 22 is EINVAL. Phew. --- lib/spack/spack/build_environment.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 571f0f8c49..e41edc14f8 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -54,6 +54,7 @@ calls you can make from within the install() function. import inspect import multiprocessing import os +import errno import shutil import sys import traceback @@ -577,8 +578,15 @@ def fork(pkg, function, dirty=False): parent_connection, child_connection = multiprocessing.Pipe() try: # Forward sys.stdin to be able to activate / deactivate - # verbosity pressing a key at run-time - input_stream = lang.duplicate_stream(sys.stdin) + # verbosity pressing a key at run-time. When sys.stdin can't + # be duplicated (e.g. running under nohup, which results in an + # '[Errno 22] Invalid argument') then just use os.devnull + try: + input_stream = lang.duplicate_stream(sys.stdin) + except OSError as e: + if e.errno == errno.EINVAL: + tty.debug("Using devnull as input_stream") + input_stream = open(os.devnull) p = multiprocessing.Process( target=child_execution, args=(child_connection, input_stream) -- cgit v1.2.3-60-g2f50