Blob Blame History Raw
diff --git a/README.md b/README.md
index f224b04..c272d09 100644
--- a/README.md
+++ b/README.md
@@ -186,7 +186,8 @@ then just `pip install dumb-init`.
 ## Usage
 
 Once installed inside your Docker container, simply prefix your commands with
-`dumb-init`.
+`dumb-init` (and make sure that you're using [the recommended JSON
+syntax][docker-cmd-json]).
 
 Within a Dockerfile, it's a good practice to use dumb-init as your container's
 entrypoint. An "entrypoint" is a partial command that gets prepended to your
@@ -209,6 +210,10 @@ Running this same command without `dumb-init` would result in being unable to
 stop the container without `SIGKILL`, but with `dumb-init`, you can send it
 more humane signals like `SIGTERM`.
 
+It's important that you use [the JSON syntax][docker-cmd-json] for `CMD` and
+`ENTRYPOINT`. Otherwise, Docker invokes a shell to run your command, resulting
+in the shell as PID 1 instead of dumb-init.
+
 
 ## Building dumb-init
 
@@ -255,3 +260,4 @@ your machine.
 [systemd]: https://wiki.freedesktop.org/www/Software/systemd/
 [sysvinit]: https://wiki.archlinux.org/index.php/SysVinit
 [docker]: https://www.docker.com/
+[docker-cmd-json]: https://docs.docker.com/engine/reference/builder/#run
diff --git a/testing/__init__.py b/testing/__init__.py
index ef2d543..1d87f30 100644
--- a/testing/__init__.py
+++ b/testing/__init__.py
@@ -50,14 +50,17 @@ def child_pids(pid):
     """Return a list of direct child PIDs for the given PID."""
     children = set()
     for p in LocalPath('/proc').listdir():
-        stat = p.join('stat')
-        if stat.isfile():
-            stat = stat.open().read()
-            m = re.match('^\d+ \([^\)]+\) [a-zA-Z] (\d+) ', stat)
+        try:
+            stat = open(p.join('stat').strpath).read()
+            m = re.match('^\d+ \(.+?\) [a-zA-Z] (\d+) ', stat)
             assert m, stat
             ppid = int(m.group(1))
             if ppid == pid:
                 children.add(int(p.basename))
+        except IOError:
+            # Happens when the process exits after listing it, or between
+            # opening stat and reading it.
+            pass
     return children
 
 
diff --git a/tests/exit_status_test.py b/tests/exit_status_test.py
index bb7be1d..f67a17c 100644
--- a/tests/exit_status_test.py
+++ b/tests/exit_status_test.py
@@ -1,4 +1,5 @@
 import signal
+import sys
 from subprocess import Popen
 
 import pytest
@@ -17,7 +18,7 @@ def test_exit_status_regular_exit(exit_status):
 
 @pytest.mark.parametrize('signal', [
     signal.SIGTERM,
-    signal.SIGINT,
+    signal.SIGHUP,
     signal.SIGQUIT,
     signal.SIGKILL,
 ])
@@ -26,6 +27,10 @@ def test_exit_status_terminated_by_signal(signal):
     """dumb-init should exit with status 128 + signal when the child process is
     terminated by a signal.
     """
-    proc = Popen(('dumb-init', 'sh', '-c', 'kill -{0} $$'.format(signal)))
+    # We use Python because sh is "dash" on Debian and "bash" on others.
+    # https://github.com/Yelp/dumb-init/issues/115
+    proc = Popen(('dumb-init', sys.executable, '-c', 'import os; os.kill(os.getpid(), {0})'.format(
+        signal,
+    )))
     proc.wait()
     assert proc.returncode == 128 + signal