diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
index 2069be1..a18860a 100644
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -74,6 +74,7 @@ from IPython.kernel.zmq.session import default_secure, Session
from IPython.nbformat.sign import NotebookNotary
from IPython.utils.importstring import import_item
from IPython.utils import submodule
+from IPython.utils.process import check_pid
from IPython.utils.traitlets import (
Dict, Unicode, Integer, List, Bool, Bytes, Instance,
DottedObjectName, TraitError,
@@ -841,6 +842,7 @@ class NotebookApp(BaseIPythonApplication):
'secure': bool(self.certfile),
'base_url': self.base_url,
'notebook_dir': os.path.abspath(self.notebook_dir),
+ 'pid': os.getpid()
}
def write_server_info_file(self):
@@ -914,8 +916,17 @@ def list_running_servers(profile='default'):
for file in os.listdir(pd.security_dir):
if file.startswith('nbserver-'):
with io.open(os.path.join(pd.security_dir, file), encoding='utf-8') as f:
- yield json.load(f)
+ info = json.load(f)
+ # Simple check whether that process is really still running
+ if check_pid(info['pid']):
+ yield info
+ else:
+ # If the process has died, try to delete its info file
+ try:
+ os.unlink(file)
+ except OSError:
+ pass # TODO: This should warn or log or something
#-----------------------------------------------------------------------------
# Main entry point
#-----------------------------------------------------------------------------
diff --git a/IPython/parallel/apps/baseapp.py b/IPython/parallel/apps/baseapp.py
index fa645fd..fc06304 100644
--- a/IPython/parallel/apps/baseapp.py
+++ b/IPython/parallel/apps/baseapp.py
@@ -36,6 +36,7 @@ from IPython.core.application import (
base_flags as base_ip_flags
)
from IPython.utils.path import expand_path
+from IPython.utils.process import check_pid
from IPython.utils import py3compat
from IPython.utils.py3compat import unicode_type
@@ -249,28 +250,11 @@ class BaseParallelApplication(BaseIPythonApplication):
raise PIDFileError('pid file not found: %s' % pid_file)
def check_pid(self, pid):
- if os.name == 'nt':
- try:
- import ctypes
- # returns 0 if no such process (of ours) exists
- # positive int otherwise
- p = ctypes.windll.kernel32.OpenProcess(1,0,pid)
- except Exception:
- self.log.warn(
- "Could not determine whether pid %i is running via `OpenProcess`. "
- " Making the likely assumption that it is."%pid
- )
- return True
- return bool(p)
- else:
- try:
- p = Popen(['ps','x'], stdout=PIPE, stderr=PIPE)
- output,_ = p.communicate()
- except OSError:
- self.log.warn(
- "Could not determine whether pid %i is running via `ps x`. "
- " Making the likely assumption that it is."%pid
- )
- return True
- pids = list(map(int, re.findall(br'^\W*\d+', output, re.MULTILINE)))
- return pid in pids
+ try:
+ return check_pid(pid)
+ except Exception:
+ self.log.warn(
+ "Could not determine whether pid %i is running. "
+ " Making the likely assumption that it is."%pid
+ )
+ return True
diff --git a/IPython/utils/_process_posix.py b/IPython/utils/_process_posix.py
index 9c6054f..07be022 100644
--- a/IPython/utils/_process_posix.py
+++ b/IPython/utils/_process_posix.py
@@ -16,6 +16,8 @@ This file is only meant to be imported by process.py, not by end-users.
from __future__ import print_function
# Stdlib
+import errno
+import os
import subprocess as sp
import sys
@@ -209,5 +211,15 @@ class ProcessHandler(object):
# (ls is a good example) that makes them hard.
system = ProcessHandler().system
-
-
+def check_pid(pid):
+ try:
+ os.kill(pid, 0)
+ except OSError as err:
+ if err.errno == errno.ESRCH:
+ return False
+ elif err.errno == errno.EPERM:
+ # Don't have permission to signal the process - probably means it exists
+ return True
+ raise
+ else:
+ return True
diff --git a/IPython/utils/_process_win32.py b/IPython/utils/_process_win32.py
index 8b30c23..3ac59b2 100644
--- a/IPython/utils/_process_win32.py
+++ b/IPython/utils/_process_win32.py
@@ -185,3 +185,8 @@ try:
return result
except AttributeError:
arg_split = py_arg_split
+
+def check_pid(pid):
+ # OpenProcess returns 0 if no such process (of ours) exists
+ # positive int otherwise
+ return bool(ctypes.windll.kernel32.OpenProcess(1,0,pid))
diff --git a/IPython/utils/process.py b/IPython/utils/process.py
index a7a54ea..2a19945 100644
--- a/IPython/utils/process.py
+++ b/IPython/utils/process.py
@@ -21,11 +21,11 @@ import sys
# Our own
if sys.platform == 'win32':
- from ._process_win32 import _find_cmd, system, getoutput, arg_split
+ from ._process_win32 import _find_cmd, system, getoutput, arg_split, check_pid
elif sys.platform == 'cli':
from ._process_cli import _find_cmd, system, getoutput, arg_split
else:
- from ._process_posix import _find_cmd, system, getoutput, arg_split
+ from ._process_posix import _find_cmd, system, getoutput, arg_split, check_pid
from ._process_common import getoutputerror, get_output_error_code, process_handler
from . import py3compat