summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2016-03-10 03:30:03 +0100
committerAlexander Sulfrian <alexander@sulfrian.net>2016-03-10 03:30:03 +0100
commit2a9bcee9e665da5af4f27b8d54b6d89f458805b1 (patch)
tree51898d99bceac0d3895f8720b02ba6e8fff242b3
parent9ac127450231ac12772b36f9794d3336f2615e85 (diff)
parent5c897e15cef7edce935c3bd222dd3d5c0a6956f1 (diff)
downloadspline-startup-2a9bcee9e665da5af4f27b8d54b6d89f458805b1.tar.gz
spline-startup-2a9bcee9e665da5af4f27b8d54b6d89f458805b1.tar.bz2
spline-startup-2a9bcee9e665da5af4f27b8d54b6d89f458805b1.zip
Merge commit '1.5' into debian
* commit '1.5': Bump version Non-Blocking read of subprocess output Ignore SIGCHLD to cleanup child and remove defunct processes Use correct variable
-rwxr-xr-xspline-startup62
1 files changed, 54 insertions, 8 deletions
diff --git a/spline-startup b/spline-startup
index 2c7dc54..fc1404f 100755
--- a/spline-startup
+++ b/spline-startup
@@ -2,15 +2,18 @@
from __future__ import print_function
import argparse
+import fcntl
import os
import pwd
+import select
+import signal
import sys
import syslog
from subprocess import Popen, PIPE, STDOUT
from pipes import quote
-VERSION = '1.4'
+VERSION = '1.5'
def is_root():
@@ -40,6 +43,51 @@ def _get_users(config):
return users
+class Executor(Popen):
+ def __init__(self, *args, **kwargs):
+ self.running = True
+
+ self.orig_signal = signal.signal(signal.SIGCHLD, self._signal)
+ return super(Executor, self).__init__(*args, **kwargs)
+
+ def readlines(self):
+ fl = fcntl.fcntl(self.stdout, fcntl.F_GETFL)
+ fcntl.fcntl(self.stdout, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+
+ buffer = ''
+ while self.running:
+ try:
+ ready = select.select([self.stdout], [], [], 0)
+ except select.error:
+ pass
+
+ if ready[0] != []:
+ buffer += self.stdout.read(8192)
+ lines = buffer.splitlines()
+ for line in lines[:-1]:
+ yield line
+ if len(lines) > 0:
+ buffer = lines[-1]
+
+ self.wait()
+
+ try:
+ buffer += self.stdout.read(8192)
+ except:
+ pass
+
+ for line in buffer.splitlines():
+ yield line
+
+ def wait(self):
+ result = super(Executor, self).wait()
+ signal.signal(signal.SIGCHLD, self.orig_signal)
+ return result
+
+ def _signal(self, *args):
+ self.running = False
+
+
class SplineStartup(object):
def __init__(self):
@@ -103,12 +151,9 @@ class SplineStartup(object):
def _call(self, cmd):
self._pinfo('Calling: %s' % ' '.join(cmd))
if not self.options.dry_run:
- proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
- output, _ = proc.communicate()
- output = output.strip()
- if output != '':
- for line in output.split('\n'):
- self._pinfo(line)
+ proc = Executor(cmd, stdout=PIPE, stderr=STDOUT)
+ for line in proc.readlines():
+ self._pinfo(line)
return proc.returncode
else:
return 0
@@ -166,7 +211,7 @@ class SplineStartup(object):
user = pwd.getpwnam(username)
self._run_scripts(user, self.options.actions)
except KeyError:
- self._perror("Invalid user '%s'" % user)
+ self._perror("Invalid user '%s'" % username)
else:
userlist = _get_users(self.options.config)
for user in userlist:
@@ -174,6 +219,7 @@ class SplineStartup(object):
def main():
+ signal.signal(signal.SIGCHLD, signal.SIG_IGN)
app = SplineStartup()
app.run()