コード例 #1
0
ファイル: duct.py プロジェクト: nbv1982/duct.py
    def wait(self):
        with self._wait_lock:
            # See if another thread already waited. If so, return the status we
            # got before. If not, immediately release the status lock, and move
            # on to call wait ourselves.
            with self._status_lock:
                if self._status is not None:
                    return self._status

            # No other thread has waited, we're holding the wait lock, and
            # we've released the status lock. It's now our job to wait. As
            # documented above, if os.waitid is defined, use that function to
            # await the child without reaping it. Otherwise we do an ordinary
            # Popen.wait and accept the race condition on some platforms.
            if HAS_WAITID:
                os.waitid(os.P_PID, self._child.pid, os.WEXITED | os.WNOWAIT)
            else:
                # Python does synchronize this internally, so it won't race
                # with other calls to wait() or poll(). Unfortunately it still
                # races with kill(), which is what all of this is about.
                self._child.wait()

            # Finally, while still holding the wait lock, re-acquire the status
            # lock to reap the child and write the result. Since we know the
            # child has already exited, this won't block. Any other waiting
            # threads that were blocked on us will see our result.
            with self._status_lock:
                # If the child was already reaped above in the !HAS_WAITID
                # branch, this will just return the same status again.
                self._status = self._child.wait()
                return self._status
コード例 #2
0
def run_watchdog(args):
    watchdog = multiprocessing.Value('d', time.time() + 1)
    pid = os.fork()
    if pid == 0:
        run(args, watchdog=watchdog)
    else:
        install_sighandler()
        while last_signal is None:
            if time.time() - watchdog.value >= args.watchdog:
                logger.error("Child is not responding, killing")
                os.kill(pid, signal.SIGKILL)
                return True

            res = os.waitid(os.P_PID, pid, os.WEXITED | os.WNOHANG)
            if res is not None:
                if res.si_code !=0:
                    logger.error("Child exited with code %d, restarting", res.si_code)
                    return True

        logger.info("Killing child with signal %d", last_signal)
        os.kill(pid, last_signal)
        s = time.time()
        while time.time() - s < 1:
            res = os.waitid(os.P_PID, pid, os.WEXITED | os.WNOHANG)
            if res is not None:
                break
        if res is None:
            logger.error("Killing child")
            os.kill(pid, signal.SIGKILL)
コード例 #3
0
    def execute(self, cmd):
        """Execute command in container.

        cmd is a string which is executed within a bash shell.
        """

        import os
        import subprocess
        import sys

        options.log.info("%s %s" % (self.cid[:6], cmd))
        docker_cmd = ["docker", "exec", "--interactive"]
        docker_cmd += [self.cid, "/bin/bash"]
        docker = subprocess.Popen(docker_cmd,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  stdin=subprocess.PIPE,
                                  universal_newlines=True)
        docker.stdin.write(cmd + "\n")
        docker.stdin.close()
        stdout_reader = os.fork()
        if stdout_reader == 0:
            self._reader(docker, docker.stdout, "stdout")
            sys.exit(0)
        stderr_reader = os.fork()
        if stderr_reader == 0:
            self._reader(docker, docker.stderr, "stderr")
            sys.exit(0)
        os.waitid(os.P_PID, stdout_reader, os.WEXITED)
        os.waitid(os.P_PID, stderr_reader, os.WEXITED)
        docker.wait()
        if docker.returncode != 0:
            options.log.error("running in container %s" % (str(self.cid)))
            raise Exception("failed command \"%s\"" % (cmd))
コード例 #4
0
ファイル: docker.py プロジェクト: waebbl/ebuildtester
    def execute(self, cmd):
        """Execute command in container.

        cmd is a string which is executed within a bash shell.
        """

        import os
        import subprocess
        import sys

        options.log.info("%s %s" % (self.cid[:6], cmd))
        docker_cmd = ["docker", "exec", "--interactive"]
        docker_cmd += [self.cid, "/bin/bash"]
        docker = subprocess.Popen(docker_cmd,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  stdin=subprocess.PIPE,
                                  universal_newlines=True)
        docker.stdin.write(cmd + "\n")
        docker.stdin.close()

        stdout_reader = os.fork()
        if stdout_reader == 0:
            try:
                self._reader(docker, docker.stdout, "stdout")
            except KeyboardInterrupt:
                pass
            sys.exit(0)

        stderr_reader = os.fork()
        if stderr_reader == 0:
            try:
                self._reader(docker, docker.stderr, "stderr")
            except KeyboardInterrupt:
                pass
            sys.exit(0)

        try:
            os.waitid(os.P_PID, stdout_reader, os.WEXITED)
            os.waitid(os.P_PID, stderr_reader, os.WEXITED)
            docker.wait()
        except KeyboardInterrupt:
            try:
                options.log.info("received keyboard interrupt")
                docker.terminate()
                self.shell()
                options.log.info("return from shell, initiating shutdown")
                self.cleanup()
                sys.exit(0)
            except OSError:
                pass
            docker.wait()

        if docker.returncode != 0:
            options.log.error("running in container %s" % (str(self.cid)))
            raise ExecuteFailure("failed command \"%s\"" % (cmd))
コード例 #5
0
 def wait_for_children(self):
     # forward signal to children
     for signum in (
             signal.SIGINT,
             signal.SIGTERM,
             signal.SIGHUP,
             signal.SIGQUIT,
             signal.SIGABRT,
             signal.SIGWINCH,
             signal.SIGUSR1,
             signal.SIGUSR2,
     ):
         signal.signal(signum, self._signal_children)
     # just wait for them
     pgid = os.getpgid(self.pid)
     os.waitid(os.P_PGID, pgid, os.WEXITED)
コード例 #6
0
def run_test_case(path):
    pid = os.fork()
    if not pid:
        # child
        result = doctest.testfile(path)
        if result.failed == 0:
            s = 'pass'
            st = 0
        else:
            s = 'fail'
            st = 1

        print('[%s] %s' % (s, path))
        sys.exit(st)
    else:
        # parent
        while True:
            try:
                r = os.waitid(
                    os.P_PID, pid, os.WEXITED | os.WSTOPPED | os.WCONTINUED
                    | os.WNOWAIT | os.WNOHANG)
            except ChildProcessError:
                pass

            if not r:
                time.sleep(0.1)
                continue

            #print('Child PID %d exited with status %d' % (pid, r.si_status))
            break
コード例 #7
0
def reap_children(active_children: set) -> None:
    for child_pid in active_children.copy():
        active_child_pid, _ = os.waitid(child_pid, os.WNOHANG)
        if active_child_pid:
            active_children.discard(active_child_pid)

    pass
コード例 #8
0
ファイル: autotester.py プロジェクト: woggle/archimedes
 def status(self):
     """
     Returns one of
     
     "pending"           - not yet begun (will begin if resources to do so available)
     "running"           - still running
     "finished"          - completed, ready to be removed
     "crashed"           - completed with non-0 exit code
     "wallclock timeout" - killed by time check
     "cpu timeout"       - killed by rlimit check
     """
     import time
     if self._status == 'pending' and PIDWrap.count < PIDWrap.limit:
         self.begin()
     if self._status == 'running':
         ans = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
         if ans is None:
             if time.time() >= self.killat:
                 os.kill(self.pid, 9)
                 os.waitpid(self.pid, 0)
                 self._status = 'wallclock timeout'
             else:
                 self._status = 'running'
         elif ans.si_status == 24:
             self._status = 'cpu timeout'
         elif ans.si_status != 0:
             self._status = 'crashed'
         else:
             self._status = 'finished'
         if self._status != 'running': PIDWrap.count -= 1
     return self._status
コード例 #9
0
ファイル: sasiostdio.py プロジェクト: thakurgurjot/saspy
   def _getlog(self, wait=5, jobid=None):
      logf   = b''
      quit   = wait * 2
      logn   = self._logcnt(False)
      code1  = "%put E3969440A681A24088859985"+logn+";\nE3969440A681A24088859985"+logn

      while True:
         log = self.stderr.read1(4096)
         if len(log) > 0:
            logf += log
         else:
            quit -= 1
            if quit < 0 or len(logf) > 0:
               break
            sleep(0.5)

      x = logf.decode(self.sascfg.encoding, errors='replace').replace(code1, " ")
      self._log += x

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      return x
コード例 #10
0
ファイル: sasiostdio.py プロジェクト: thakurgurjot/saspy
   def _getlsttxt(self, wait=5, jobid=None):
      f2 = [None]
      lstf = b''
      quit = wait * 2
      eof = 0
      self._asubmit("data _null_;file print;put 'Tom was here';run;", "text")

      while True:
         lst = self.stdout.read1(4096)
         if len(lst) > 0:
            lstf += lst

            lenf = len(lstf)
            eof = lstf.find(b"Tom was here", lenf - 25, lenf)

            if (eof != -1):
               final = lstf.partition(b"Tom was here")
               f2 = final[0].decode(self.sascfg.encoding, errors='replace').rpartition(chr(12))
               break

      lst = f2[0]

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      return lst.replace(chr(12), '\n')
コード例 #11
0
ファイル: sasiostdio.py プロジェクト: metllord/saspy
   def _getlsttxt(self, wait=5, jobid=None):
      f2 = [None]
      lstf = b''
      quit = wait * 2
      eof = 0
      self._asubmit("data _null_;file print;put 'Tom was here';run;", "text")
   
      while True:
         lst = self.stdout.read1(4096)
         if len(lst) > 0:
            lstf += lst
   
            lenf = len(lstf)
            eof = lstf.find(b"Tom was here", lenf - 25, lenf)
      
            if (eof != -1):
               final = lstf.partition(b"Tom was here")
               f2 = final[0].decode(self.sascfg.encoding).rpartition(chr(12))
               break

      lst = f2[0]

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      return lst.replace(chr(12), '\n')
コード例 #12
0
async def child_waiter(app):
    while True:
        try:
            status = os.waitid(os.P_ALL, 0, os.WNOHANG | os.WEXITED)
            logger.debug("Child completed with status %s", str(status))
        except ChildProcessError:
            await asyncio.sleep(600)
コード例 #13
0
ファイル: sasiostdio.py プロジェクト: metllord/saspy
   def _getlog(self, wait=5, jobid=None):
      logf   = b''
      quit   = wait * 2
      logn   = self._logcnt(False)
      code1  = "%put E3969440A681A24088859985"+logn+";\nE3969440A681A24088859985"+logn

      while True:
         log = self.stderr.read1(4096)
         if len(log) > 0:
            logf += log
         else:
            quit -= 1
            if quit < 0 or len(logf) > 0:
               break
            sleep(0.5)
   
      x = logf.decode(self.sascfg.encoding).replace(code1, " ")
      self._log += x

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      return x
コード例 #14
0
ファイル: duct.py プロジェクト: nbv1982/duct.py
    def try_wait(self):
        with self._status_lock:
            if self._status is not None:
                return self._status

            # The child hasn't been waited on yet, so we need to do a
            # non-blocking check to see if it's still running. The Popen type
            # provides the poll() method for this, but that might reap the
            # child and free its PID, which would make this a race with
            # concurrent callers of the blocking wait() method above, who might
            # be about to call os.waitid on that PID. When os.waitid is
            # available, use that again here, with the WNOHANG flag. Otherwise
            # just use poll() and rely on Python's internal synchronization.
            if HAS_WAITID:
                poll_result = os.waitid(os.P_PID, self._child.pid,
                                        os.WEXITED | os.WNOWAIT | os.WNOHANG)
            else:
                poll_result = self._child.poll()

        # If either of the poll approaches above returned non-None, do a full
        # wait to reap the child, which will not block. Note that we've
        # released the status lock here, because wait() will re-acquire it.
        if poll_result is not None:
            return self.wait()
        else:
            return None
コード例 #15
0
def spawn_daemon(function, *args, **kwargs):
    # First fork
    pid = os.fork()
    if pid != 0:  # parent returns
        os.waitid(os.P_PID, pid, os.WEXITED)
        return

    # Decouple from parent environment
    # os.chdir("/")
    os.setsid()
    os.umask(0)

    # Do second fork
    pid = os.fork()
    if pid != 0:  # parent exits
        os._exit(0)

    function(*args, **kwargs)
コード例 #16
0
    def initialize_vim(working_path, pipe_name):

        """
        Initialize the vim process along with creating a named pipe to communicate with it
        :param working_path: working path of main.py and other files
        :param pipe_name: pathname of pipe to be created
        :return: pid of vim process
        """

        # File initializations relative to working paths
        plugin_file = os.path.join(working_path, "plugin.vim")

        # Make our pipe.
        utils.remove_file(pipe_name)
        os.mkfifo(pipe_name)

        # Create the vim command that opens up vim instance in new terminal
        # with proper settings, etc.
        profile_path = os.path.join(working_path, "profile.log")
        startup_command = "call AutoLogInfo() | profile start " + profile_path + " | profile func * | profile file *"
        vim_command = "vim -S %r -c %r" % (plugin_file, startup_command)

        # Send command to open up new process, wait for command process to die
        # before getting the pid of the actual vim process
        args = [env_command[desktop_env], "-e", vim_command]
        proc = subprocess.Popen(args).pid
        os.waitid(os.P_PID, int(proc), os.WEXITED)
        while True:
            try:
                logging.debug(vim_command)
                proc = (
                    subprocess.Popen(["pgrep", "-f", vim_command[:7]], stdout=subprocess.PIPE)
                    .stdout.read()
                    .decode("utf-8")
                    .rstrip()
                )
                logging.debug(proc)
                proc = int(proc)
                break
            except:
                pass
        return proc
コード例 #17
0
ファイル: sasiostdio.py プロジェクト: renewday/saspy
 def _endsas(self):
    rc = 0
    if self.pid:
       code = ";*\';*\";*/;\n;quit;endsas;"
       self._getlog(wait=1)
       self._asubmit(code,'text')
       sleep(1)
       try:
          rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
       except (subprocess.TimeoutExpired):
          print("SAS didn't shutdown w/in 5 seconds; killing it to be sure")
          os.kill(self.pid, signal.SIGKILL)
       print("SAS Connection terminated. Subprocess id was "+str(self.pid))
       self.pid = None
    return rc
コード例 #18
0
ファイル: sasbase.py プロジェクト: dlawregiets/saspy
 def _endsas(self):
     rc = 0
     if self.pid:
         code = b";*\';*\";*/;\n;quit;endsas;\n"
         self.stderr.read1(4096)
         self.stdin.write(code)
         self.stdin.flush()
         sleep(1)
         try:
             rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
         except subprocess.TimeoutExpired:
             print("SAS didn't shutdown w/in 5 seconds; killing it to be sure")
             os.kill(self.pid, signal.SIGKILL)
         self.pid = None
     return rc
コード例 #19
0
 def sync_wait_reapable(pid):
     P_PID = 1
     WEXITED = 0x00000004
     if sys.platform == 'darwin':  # pragma: no cover
         # waitid() is not exposed on Python on Darwin but does
         # work through CFFI; note that we typically won't get
         # here since Darwin also defines kqueue
         WNOWAIT = 0x00000020
     else:
         WNOWAIT = 0x01000000
     result = waitid_ffi.new("siginfo_t *")
     while waitid(P_PID, pid, result, WEXITED | WNOWAIT) < 0:
         got_errno = waitid_ffi.errno
         if got_errno == errno.EINTR:
             continue
         raise OSError(got_errno, os.strerror(got_errno))
コード例 #20
0
 def _endsas(self):
     rc = 0
     if self.pid:
         code = b";*\';*\";*/;\n;quit;endsas;\n"
         self.stderr.read1(4096)
         self.stdin.write(code)
         self.stdin.flush()
         sleep(1)
         try:
             rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
         except subprocess.TimeoutExpired:
             print(
                 "SAS didn't shutdown w/in 5 seconds; killing it to be sure"
             )
             os.kill(self.pid, signal.SIGKILL)
         self.pid = None
     return rc
コード例 #21
0
 def _handle_SIGCHLD(self, pid):
     _logger.debug("calling waitid() on process %d", pid)
     waitid_result = os.waitid(os.P_PID, pid, os.WNOHANG | os.WEXITED)
     _logger.debug("waitid() returned %r", waitid_result)
     if waitid_result is None:
         _logger.warning("waitid() returned nothing?")
         return
     if waitid_result.si_code == CLD_EXITED:
         returncode = waitid_result.si_status
         _logger.debug("Saw CLD_EXITED with return code: %r", returncode)
         return returncode
     elif waitid_result.si_code == CLD_KILLED:
         signal_num = waitid_result.si_status
         _logger.debug("Saw CLD_KILLED with signal: %r", signal_num)
         return -signal_num
     else:
         _bug_logger.error("Unexpected si_code: %d", waitid_result.si_code)
コード例 #22
0
 def status(self):
     import time
     if self._status == 'pending' and PIDWrap.count < PIDWrap.limit:
         self.begin()
     if self._status == 'running':
         ans = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
         if ans is None:
             if time.time() >= self.killat:
                 os.kill(self.pid, 9)
                 os.waitpid(self.pid, 0)
                 self._status = 'wallclock timeout'
             else:
                 self._status = 'running'
         elif ans.si_status == 24:
             self._status = 'cpu timeout'
         elif ans.si_status != 0:
             self._status = 'crashed'
         else:
             self._status = 'finished'
         if self._status != 'running': PIDWrap.count -= 1
     return self._status
コード例 #23
0
ファイル: sasiostdio.py プロジェクト: thakurgurjot/saspy
   def _getlst(self, wait=5, jobid=None):
      lstf = b''
      quit = wait * 2
      eof = 0
      bof = False
      lenf = 0

      while True:
         lst = self.stdout.read1(4096)
         if len(lst) > 0:
            lstf += lst

            if ((not bof) and lst.count(b"<!DOCTYPE html>", 0, 20) > 0):
               bof = True
         else:
            lenf = len(lstf)

            if (lenf > 15):
               eof = lstf.count(b"</html>", (lenf - 15), lenf)

            if (eof > 0):
                  break

            if not bof:
               quit -= 1
               if quit < 0:
                  break
               sleep(0.5)

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      if eof:
         return lstf.decode(errors='replace')
      else:
         return lstf.decode(self.sascfg.encoding, errors='replace')
コード例 #24
0
ファイル: sasiostdio.py プロジェクト: metllord/saspy
   def _getlst(self, wait=5, jobid=None):
      lstf = b''
      quit = wait * 2
      eof = 0
      bof = False
      lenf = 0
   
      while True:
         lst = self.stdout.read1(4096)
         if len(lst) > 0:
            lstf += lst
                             
            if ((not bof) and lst.count(b"<!DOCTYPE html>", 0, 20) > 0):
               bof = True
         else:
            lenf = len(lstf)
      
            if (lenf > 15):
               eof = lstf.count(b"</html>", (lenf - 15), lenf)
      
            if (eof > 0):
                  break
            
            if not bof:
               quit -= 1
               if quit < 0:
                  break
               sleep(0.5)

      if self.pid == None:
         return "No SAS process attached. SAS process has terminated unexpectedly."
      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return 'SAS process has terminated unexpectedly. Pid State= '+str(rc)

      return lstf.decode(self.sascfg.encoding)
コード例 #25
0
    def wait_process(self):

        siginfo = os.waitid(os.P_PID, self.process_dmtcp_wrapped.pid,
                            os.WEXITED | os.WNOWAIT)
        self.process_dmtcp_wrapped.wait()

        states.setProcessFinished()

        CLD_KILLED = 3

        if siginfo.si_code == CLD_KILLED:
            utils.stderr_and_log(
                "Process recevied signal: %s" %
                signals.strsignal(siginfo.si_status), logger)

        self.returncode = self.process_dmtcp_wrapped.returncode

        if self.returncode == 0:
            context.plugin_hook.done(exeinfo=self)
            # TODO check rerunable fail
        else:
            context.plugin_hook.fail(exeinfo=self)
        logger.info("Process to be checkpointed finished with ret code :%d." %
                    self.returncode)
コード例 #26
0
    def submit(self, code, results="html", prompt={}):
        odsopen = b"ods listing close;ods html5 file=stdout options(bitmap_mode='inline') device=png; ods graphics on / outputfmt=png;\n"
        odsclose = b"ods html5 close;ods listing;\n"
        ods = True
        mj = b";*\';*\";*/;"
        lstf = ''
        logf = ''
        bail = False
        eof = 5
        bc = False
        done = False
        logn = self._logcnt()
        logcodei = "%put E3969440A681A24088859985" + logn + ";"
        logcodeo = "\nE3969440A681A24088859985" + logn
        pcodei = ''
        pcodeo = ''

        if self.pid is None:
            print(
                "No SAS process attached. SAS process has terminated unexpectedly."
            )
            return dict(
                LOG=
                "No SAS process attached. SAS process has terminated unexpectedly.",
                LST='')

        rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
        if rc is not None:
            self.pid = None
            return dict(
                LOG='SAS process has terminated unexpectedly. Pid State= ' +
                str(rc),
                LST='')

        if results.upper() != "HTML":
            ods = False

        if len(prompt):
            pcodei += 'options nosource nonotes;\n'
            pcodeo += 'options nosource nonotes;\n'
            for key in prompt:
                gotit = False
                while not gotit:
                    var = self.sascfg._prompt(
                        'Please enter value for macro variable ' + key + ' ',
                        pw=prompt[key])
                    if len(var) > 0:
                        gotit = True
                    else:
                        print("Sorry, didn't get a value for that variable.")
                pcodei += '%let ' + key + '=' + var + ';\n'
                pcodeo += '%symdel ' + key + ';\n'
            pcodei += 'options source notes;\n'
            pcodeo += 'options source notes;\n'

        if ods:
            self.stdin.write(odsopen)

        out = self.stdin.write(mj + b'\n' + pcodei.encode() + code.encode() +
                               b'\n' + pcodeo.encode() + b'\n' + mj)

        if ods:
            self.stdin.write(odsclose)

        out = self.stdin.write(b'\n' + logcodei.encode() + b'\n')
        self.stdin.flush()

        while not done:
            try:
                while True:
                    rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
                    if rc is not None:
                        self.pid = None
                        return dict(
                            LOG=
                            'SAS process has terminated unexpectedly. Pid State= '
                            + str(rc),
                            LST='')
                    if bail:
                        eof -= 1
                    if eof < 0:
                        break
                    lst = self.stdout.read1(4096).decode()
                    if len(lst) > 0:
                        lstf += lst
                    else:
                        log = self.stderr.read1(4096).decode()
                        if len(log) > 0:
                            logf += log
                            if logf.count(logcodeo) >= 1:
                                bail = True
                            if not bail and bc:
                                self.stdin.write(odsclose + logcodei.encode() +
                                                 b'\n')
                                self.stdin.flush()
                                bc = False
                done = True

            except (KeyboardInterrupt, SystemExit):
                print('Exception caught!')
                ll = self._breakprompt(logcodeo)

                if ll.get('ABORT', False):
                    return ll

                logf += ll['LOG']
                lstf += ll['LST']
                bc = ll['BC']

                if not bc:
                    print('Exception handled :)\n')
                else:
                    print('Exception ignored, continuing to process...\n')

                self.stdin.write(odsclose + logcodei.encode() + b'\n')
                self.stdin.flush()

        trip = lstf.rpartition("/*]]>*/")
        if len(trip[1]) > 0 and len(trip[2]) < 100:
            lstf = ''

        self._log += logf
        final = logf.partition(logcodei)
        z = final[0].rpartition(chr(10))
        prev = '%08d' % (self._log_cnt - 1)
        zz = z[0].rpartition("\nE3969440A681A24088859985" + prev + '\n')
        logd = zz[2].replace(mj.decode(), '')

        lstd = lstf.replace(chr(12),
                            chr(10)).replace('<body class="c body">',
                                             '<body class="l body">').replace(
                                                 "font-size: x-small;",
                                                 "font-size:  normal;")
        return dict(LOG=logd, LST=lstd)
コード例 #27
0
ファイル: child.py プロジェクト: tobpe/kitty
 def get_child_status(self):
     if self.pid is not None:
         try:
             return os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
         except ChildProcessError:
             self.pid = None
コード例 #28
0
ファイル: sasbase.py プロジェクト: dlawregiets/saspy
    def submit(self, code, results="html", prompt={}):
        odsopen = b"ods listing close;ods html5 file=stdout options(bitmap_mode='inline') device=png; ods graphics on / outputfmt=png;\n"
        odsclose = b"ods html5 close;ods listing;\n"
        ods = True
        mj = b";*\';*\";*/;"
        lstf = '' 
        logf = '' 
        bail = False
        eof = 5
        bc = False
        done = False
        logn = self._logcnt()
        logcodei = "%put E3969440A681A24088859985" + logn + ";"
        logcodeo = "\nE3969440A681A24088859985" + logn
        pcodei   = ''
        pcodeiv  = ''
        pcodeo   = ''

        if self.pid is None:
            print("No SAS process attached. SAS process has terminated unexpectedly.")
            return dict(LOG="No SAS process attached. SAS process has terminated unexpectedly.", LST='')

        rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
        if rc is not None:
            self.pid = None
            return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' + str(rc), LST='')

        if results.upper() != "HTML":
            ods = False

        if len(prompt):
           pcodei += 'options nosource nonotes;\n'
           pcodeo += 'options nosource nonotes;\n'
           for key in prompt:
              gotit = False
              while not gotit:
                 var = self.sascfg._prompt('Please enter value for macro variable '+key+' ', pw=prompt[key])
                 if len(var) > 0:
                    gotit = True
                 else:
                    print("Sorry, didn't get a value for that variable.")
              if prompt[key]:
                 pcodei += '%let '+key+'='+var+';\n'
                 pcodeo += '%symdel '+key+';\n'
              else:
                 pcodeiv += '%let '+key+'='+var+';\n'
           pcodei += 'options source notes;\n'
           pcodeo += 'options source notes;\n'

        if ods:
            self.stdin.write(odsopen)

        out = self.stdin.write(mj+b'\n'+pcodei.encode()+pcodeiv.encode()+code.encode()+b'\n'+pcodeo.encode()+b'\n'+mj)

        if ods:
            self.stdin.write(odsclose)

        out = self.stdin.write(b'\n' + logcodei.encode() + b'\n')
        self.stdin.flush()

        while not done:
           try:
               while True:
                   rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
                   if rc is not None:
                       self.pid = None
                       return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' +
                                   str(rc), LST='')
                   if bail:
                       eof -= 1
                   if eof < 0:
                       break
                   lst = self.stdout.read1(4096).decode()
                   if len(lst) > 0:
                       lstf += lst
                   else:
                       log = self.stderr.read1(4096).decode() 
                       if len(log) > 0:
                           logf += log
                           if logf.count(logcodeo) >= 1:
                               bail = True
                           if not bail and bc:
                               self.stdin.write(odsclose+logcodei.encode() + b'\n')
                               self.stdin.flush()
                               bc = False
               done = True

           except (KeyboardInterrupt, SystemExit):
               print('Exception caught!')
               ll = self._breakprompt(logcodeo)

               if ll.get('ABORT', False):
                  return ll

               logf += ll['LOG']
               lstf += ll['LST']
               bc    = ll['BC']

               if not bc:
                  print('Exception handled :)\n')
               else:
                  print('Exception ignored, continuing to process...\n')

               self.stdin.write(odsclose+logcodei.encode()+b'\n')
               self.stdin.flush()

        trip = lstf.rpartition("/*]]>*/")      
        if len(trip[1]) > 0 and len(trip[2]) < 100:
           lstf = ''

        self._log += logf
        final = logf.partition(logcodei)
        z = final[0].rpartition(chr(10))
        prev = '%08d' %  (self._log_cnt - 1)
        zz = z[0].rpartition("\nE3969440A681A24088859985" + prev +'\n')
        logd = zz[2].replace(mj.decode(), '')

        lstd = lstf.replace(chr(12), chr(10)).replace('<body class="c body">',
                                                      '<body class="l body">').replace("font-size: x-small;",
                                                                                       "font-size:  normal;")
        return dict(LOG=logd, LST=lstd)
コード例 #29
0
ファイル: sasbase.py プロジェクト: aabbasi/saspy
    def submit(self, code, results="html"):
        odsopen = b"ods listing close;ods html5 file=stdout options(bitmap_mode='inline') device=png; ods graphics on / outputfmt=png;\n"
        odsclose = b"ods html5 close;ods listing;\n"
        ods = True
        htm = "html HTML"
        mj = b";*\';*\";*/;"
        lstf = '' 
        logf = '' 
        bail = False
        eof = 5
        bc = False
        done = False
        logn = self._logcnt()
        logcodei = "%put E3969440A681A24088859985" + logn + ";"
        logcodeo = "\nE3969440A681A24088859985" + logn

        if self.pid is None:
            return dict(LOG="No SAS process attached. SAS process has terminated unexpectedly.", LST='')

        rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
        if rc is not None:
            self.pid = None
            return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' + str(rc), LST='')

        if htm.find(results) < 0:
            ods = False

        if ods:
            self.stdin.write(odsopen)

        out = self.stdin.write(mj + b'\n' + code.encode() + b'\n' + mj)

        if ods:
            self.stdin.write(odsclose)

        out = self.stdin.write(b'\n' + logcodei.encode() + b'\n')
        self.stdin.flush()

        while not done:
           try:
               while True:
                   rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
                   if rc is not None:
                       self.pid = None
                       return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' +
                                   str(rc), LST='')
                   if bail:
                       eof -= 1
                   if eof < 0:
                       break
                   lst = self.stdout.read1(4096).decode()
                   if len(lst) > 0:
                       lstf += lst
                   else:
                       log = self.stderr.read1(4096).decode() 
                       if len(log) > 0:
                           logf += log
                           if logf.count(logcodeo) >= 1:
                               bail = True
                           if not bail and bc:
                               self.stdin.write(odsclose+logcodei.encode() + b'\n')
                               self.stdin.flush()
                               bc = False
               done = True

           except (KeyboardInterrupt, SystemExit):
               print('Exception caught!')
               ll = self._breakprompt(logcodeo)

               if ll.get('ABORT', False):
                  return ll

               logf += ll['LOG']
               lstf += ll['LST']
               bc    = ll['BC']

               if not bc:
                  print('Exception handled :)\n')
               else:
                  print('Exception ignored, continuing to process...\n')

               self.stdin.write(odsclose+logcodei.encode()+b'\n')
               self.stdin.flush()

        trip = lstf.rpartition("/*]]>*/")      
        if len(trip[1]) > 0 and len(trip[2]) < 100:
           lstf = ''

        self._log += logf
        final = logf.partition(logcodei)
        z = final[0].rpartition(chr(10))
        prev = '%08d' %  (self._log_cnt - 1)
        zz = z[0].rpartition("\nE3969440A681A24088859985" + prev +'\n')
        logd = zz[2].replace(mj.decode(), '')

        lstd = lstf.replace(chr(12), chr(10)).replace('<body class="c body">',
                                                      '<body class="l body">').replace("font-size: x-small;",
                                                                                       "font-size:  normal;")
        return dict(LOG=logd, LST=lstd)
コード例 #30
0
ファイル: sasiostdio.py プロジェクト: thakurgurjot/saspy
   def submit(self, code: str, results: str ="html", prompt: dict ={}) -> dict:
      '''
      This method is used to submit any SAS code. It returns the Log and Listing as a python dictionary.
      code    - the SAS statements you want to execute
      results - format of results, HTML is default, TEXT is the alternative
      prompt  - dict of names:flags to prompt for; create macro variables (used in submitted code), then keep or delete
                The keys are the names of the macro variables and the boolean flag is to either hide what you type and delete
                the macros, or show what you type and keep the macros (they will still be available later)
                for example (what you type for pw will not be displayed, user and dsname will):

                results = sas.submit(
                   """
                   libname tera teradata server=teracop1 user=&user pw=&pw;
                   proc print data=tera.&dsname (obs=10); run;
                   """ ,
                   prompt = {'user': False, 'pw': True, 'dsname': False}
                   )

      Returns - a Dict containing two keys:values, [LOG, LST]. LOG is text and LST is 'results' (HTML or TEXT)

      NOTE: to view HTML results in the ipykernel, issue: from IPython.display import HTML  and use HTML() instead of print()
      i.e,: results = sas.submit("data a; x=1; run; proc print;run')
            print(results['LOG'])
            HTML(results['LST'])
      '''
      odsopen  = b"ods listing close;ods "+self.sascfg.output.encode()+ \
                 b" (id=saspy_internal) file=stdout options(bitmap_mode='inline') device=svg style="+self._sb.HTML_Style.encode()+ \
                 b"; ods graphics on / outputfmt=png;\n"
      odsclose = b"ods "+self.sascfg.output.encode()+b" (id=saspy_internal) close;ods listing;\n"
      ods      = True;
      mj       = b";*\';*\";*/;"
      lstf     = ''
      logf     = ''
      bail     = False
      eof      = 5
      bc       = False
      done     = False
      logn     = self._logcnt()
      logcodei = "%put E3969440A681A24088859985" + logn + ";"
      logcodeo = "\nE3969440A681A24088859985" + logn
      pcodei   = ''
      pcodeiv  = ''
      pcodeo   = ''

      if self.pid == None:
         print("No SAS process attached. SAS process has terminated unexpectedly.")
         return dict(LOG="No SAS process attached. SAS process has terminated unexpectedly.", LST='')

      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return dict(LOG='SAS process has terminated unexpectedly. Pid State= '+str(rc), LST='')

      # to cover the possibility of an _asubmit w/ lst output not read; no known cases now; used to be __flushlst__()
      # removing this and adding comment in _asubmit to use _getlst[txt] so this will never be necessary; delete later
      #while(len(self.stdout.read1(4096)) > 0):
      #   continue

      if results.upper() != "HTML":
         ods = False

      if len(prompt):
         pcodei += 'options nosource nonotes;\n'
         pcodeo += 'options nosource nonotes;\n'
         for key in prompt:
            gotit = False
            while not gotit:
               var = self.sascfg._prompt('Please enter value for macro variable '+key+' ', pw=prompt[key])
               if var is None:
                  raise KeyboardInterrupt 
               if len(var) > 0:
                  gotit = True
               else:
                  print("Sorry, didn't get a value for that variable.")
            if prompt[key]:
               pcodei += '%let '+key+'='+var+';\n'
               pcodeo += '%symdel '+key+';\n'
            else:
               pcodeiv += '%let '+key+'='+var+';\n'
         pcodei += 'options source notes;\n'
         pcodeo += 'options source notes;\n'

      if ods:
         self.stdin.write(odsopen)

      pgm  = mj+b'\n'+pcodei.encode(self.sascfg.encoding)+pcodeiv.encode(self.sascfg.encoding)
      pgm += code.encode(self.sascfg.encoding)+b'\n'+pcodeo.encode(self.sascfg.encoding)+b'\n'+mj
      out  = self.stdin.write(pgm)

      if ods:
         self.stdin.write(odsclose)

      out = self.stdin.write(b'\n'+logcodei.encode(self.sascfg.encoding)+b'\n')
      self.stdin.flush()

      while not done:
         try:
             while True:
                 rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
                 if rc is not None:
                     log = ''
                     try:
                        log = self.stderr.read1(4096).decode(self.sascfg.encoding, errors='replace')
                        if len(log) > 0:
                            logf += log
                        self._log += logf
                     except:
                        pass
                     self.pid = None
                     return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' +
                                 str(rc)+'\n'+logf, LST='')
                 if bail:
                     eof -= 1
                 if eof < 0:
                     break
                 if ods:
                    lst = self.stdout.read1(4096).decode(errors='replace')
                 else:
                    lst = self.stdout.read1(4096).decode(self.sascfg.encoding, errors='replace')
                 if len(lst) > 0:
                     lstf += lst
                 else:
                     log = self.stderr.read1(4096).decode(self.sascfg.encoding, errors='replace')
                     if len(log) > 0:
                         logf += log
                         if logf.count(logcodeo) >= 1:
                             bail = True
                         if not bail and bc:
                             self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding) + b'\n')
                             self.stdin.flush()
                             bc = False
             done = True

         except (ConnectionResetError):
             log = ''
             try:
                log = self.stderr.read1(4096).decode(self.sascfg.encoding, errors='replace')
                if len(log) > 0:
                    logf += log
                self._log += logf
             except:
                pass
             rc = 0
             rc = os.waitpid(self.pid, 0)
             self.pid = None
             return dict(LOG=logf.partition(logcodeo)[0]+'\nConnection Reset: SAS process has terminated unexpectedly. '+
                         'Pid State= '+str(rc)+'\n'+logf, LST='')

         except (KeyboardInterrupt, SystemExit):
             print('Exception caught!')
             ll = self._breakprompt(logcodeo)

             if ll.get('ABORT', False):
                return ll

             logf += ll['LOG']
             lstf += ll['LST']
             bc    = ll['BC']

             if not bc:
                print('Exception handled :)\n')
             else:
                print('Exception ignored, continuing to process...\n')

             self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding)+b'\n')
             self.stdin.flush()

      trip = lstf.rpartition("/*]]>*/")
      if len(trip[1]) > 0 and len(trip[2]) < 100:
         lstf = ''

      self._log += logf
      final = logf.partition(logcodei)
      z = final[0].rpartition(chr(10))
      prev = '%08d' %  (self._log_cnt - 1)
      zz = z[0].rpartition("\nE3969440A681A24088859985" + prev +'\n')
      logd = zz[2].replace(mj.decode(self.sascfg.encoding), '')

      lstd = lstf.replace(chr(12), chr(10)).replace('<body class="c body">',
                                                    '<body class="l body">').replace("font-size: x-small;",
                                                                                     "font-size:  normal;")
      return dict(LOG=logd, LST=lstd)
コード例 #31
0
ファイル: sasiostdio.py プロジェクト: metllord/saspy
   def submit(self, code: str, results: str ="html", prompt: dict ={}) -> dict:
      '''
      This method is used to submit any SAS code. It returns the Log and Listing as a python dictionary.
      code    - the SAS statements you want to execute 
      results - format of results, HTML is default, TEXT is the alternative
      prompt  - dict of names:flags to prompt for; create marco variables (used in submitted code), then keep or delete
                The keys are the names of the macro variables and the boolean flag is to either hide what you type and delete
                the macros, or show what you type and keep the macros (they will still be available later)
                for example (what you type for pw will not be displayed, user and dsname will):

                results = sas.submit(
                   """
                   libname tera teradata server=teracop1 user=&user pw=&pw;
                   proc print data=tera.&dsname (obs=10); run;
                   """ ,
                   prompt = {'user': False, 'pw': True, 'dsname': False}
                   )

      Returns - a Dict containing two keys:values, [LOG, LST]. LOG is text and LST is 'results' (HTML or TEXT)

      NOTE: to view HTML results in the ipykernel, issue: from IPython.display import HTML  and use HTML() instead of print()
      i.e,: results = sas.submit("data a; x=1; run; proc print;run')
            print(results['LOG'])
            HTML(results['LST']) 
      '''
      odsopen  = b"ods listing close;ods html5 (id=saspy_internal) file=stdout options(bitmap_mode='inline') device=svg; ods graphics on / outputfmt=png;\n"
      odsclose = b"ods html5 (id=saspy_internal) close;ods listing;\n"
      ods      = True;
      mj       = b";*\';*\";*/;"
      lstf     = ''
      logf     = ''
      bail     = False
      eof      = 5
      bc       = False
      done     = False
      logn     = self._logcnt()
      logcodei = "%put E3969440A681A24088859985" + logn + ";"
      logcodeo = "\nE3969440A681A24088859985" + logn
      pcodei   = ''
      pcodeiv  = ''
      pcodeo   = ''

      if self.pid == None:
         print("No SAS process attached. SAS process has terminated unexpectedly.")
         return dict(LOG="No SAS process attached. SAS process has terminated unexpectedly.", LST='')

      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         return dict(LOG='SAS process has terminated unexpectedly. Pid State= '+str(rc), LST='')

      # to cover the possibility of an _asubmit w/ lst output not read; no known cases now; used to be __flushlst__()
      # removing this and adding comment in _asubmit to use _getlst[txt] so this will never be necessary; delete later
      #while(len(self.stdout.read1(4096)) > 0):
      #   continue

      if results.upper() != "HTML":
         ods = False
   
      if len(prompt):
         pcodei += 'options nosource nonotes;\n'
         pcodeo += 'options nosource nonotes;\n'
         for key in prompt:
            gotit = False
            while not gotit:
               var = self.sascfg._prompt('Please enter value for macro variable '+key+' ', pw=prompt[key])
               if len(var) > 0:
                  gotit = True
               else:
                  print("Sorry, didn't get a value for that variable.")
            if prompt[key]:
               pcodei += '%let '+key+'='+var+';\n'
               pcodeo += '%symdel '+key+';\n'
            else:
               pcodeiv += '%let '+key+'='+var+';\n'
         pcodei += 'options source notes;\n'
         pcodeo += 'options source notes;\n'

      if ods:
         self.stdin.write(odsopen)
   
      pgm  = mj+b'\n'+pcodei.encode(self.sascfg.encoding)+pcodeiv.encode(self.sascfg.encoding)
      pgm += code.encode(self.sascfg.encoding)+b'\n'+pcodeo.encode(self.sascfg.encoding)+b'\n'+mj
      out  = self.stdin.write(pgm)
   
      if ods:
         self.stdin.write(odsclose)

      out = self.stdin.write(b'\n'+logcodei.encode(self.sascfg.encoding)+b'\n')
      self.stdin.flush()

      while not done:
         try:
             while True:
                 rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
                 if rc is not None:
                     self.pid = None
                     return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' +
                                 str(rc), LST='')
                 if bail:
                     eof -= 1
                 if eof < 0:
                     break
                 lst = self.stdout.read1(4096).decode(self.sascfg.encoding)
                 if len(lst) > 0:
                     lstf += lst
                 else:
                     log = self.stderr.read1(4096).decode(self.sascfg.encoding) 
                     if len(log) > 0:
                         logf += log
                         if logf.count(logcodeo) >= 1:
                             bail = True
                         if not bail and bc:
                             self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding) + b'\n')
                             self.stdin.flush()
                             bc = False
             done = True

         except (ConnectionResetError):
             rc = 0
             rc = os.waitpid(self.pid, 0)
             self.pid = None
             return dict(LOG=logf.partition(logcodeo)[0]+'\nConnection Reset: SAS process has terminated unexpectedly. Pid State= '+str(rc), LST='')
             
         except (KeyboardInterrupt, SystemExit):
             print('Exception caught!')
             ll = self._breakprompt(logcodeo)

             if ll.get('ABORT', False):
                return ll

             logf += ll['LOG']
             lstf += ll['LST']
             bc    = ll['BC']

             if not bc:
                print('Exception handled :)\n')
             else:
                print('Exception ignored, continuing to process...\n')

             self.stdin.write(odsclose+logcodei.encode(self.sascfg.encoding)+b'\n')
             self.stdin.flush()

      trip = lstf.rpartition("/*]]>*/")      
      if len(trip[1]) > 0 and len(trip[2]) < 100:
         lstf = ''

      self._log += logf
      final = logf.partition(logcodei)
      z = final[0].rpartition(chr(10))
      prev = '%08d' %  (self._log_cnt - 1)
      zz = z[0].rpartition("\nE3969440A681A24088859985" + prev +'\n')
      logd = zz[2].replace(mj.decode(self.sascfg.encoding), '')

      lstd = lstf.replace(chr(12), chr(10)).replace('<body class="c body">',
                                                    '<body class="l body">').replace("font-size: x-small;",
                                                                                     "font-size:  normal;")
      return dict(LOG=logd, LST=lstd)
コード例 #32
0
 def _interact_leave(self, signum, sigframe):
   while os.waitid(os.P_ALL, 0, os.WEXITED | os.WNOHANG) is not None:
     pass
コード例 #33
0
def save_output(args, output_file):
    """Run args[0] with arguments args[1:] and save standard output to output_file."""

    with open(output_file, 'w', encoding='utf-8') as f:
        p = subprocess.Popen(args, stfout=f)
        os.waitid(p.pid, 0)
コード例 #34
0
ファイル: sasiostdio.py プロジェクト: thakurgurjot/saspy
   def _startsas(self):
      #import pdb;pdb.set_trace()
      if self.pid:
         return self.pid

      pgm, parms = self._buildcommand(self.sascfg)

      s = ''
      for i in range(len(parms)):
            s += parms[i]+' '

      PIPE_READ  = 0
      PIPE_WRITE = 1

      pin  = os.pipe()
      pout = os.pipe()
      perr = os.pipe() 

      try:
         pidpty = os.forkpty()
      except:
         import pty
         pidpty = pty.fork()
         
      if pidpty[0]:
         # we are the parent

         pid = pidpty[0]
         os.close(pin[PIPE_READ])
         os.close(pout[PIPE_WRITE])
         os.close(perr[PIPE_WRITE])

      else:
         # we are the child
         signal.signal(signal.SIGINT, signal.SIG_DFL)

         os.close(0)
         os.close(1)
         os.close(2)

         os.dup2(pin[PIPE_READ],   0)
         os.dup2(pout[PIPE_WRITE], 1)
         os.dup2(perr[PIPE_WRITE], 2)

         os.close(pin[PIPE_READ])
         os.close(pin[PIPE_WRITE])
         os.close(pout[PIPE_READ])
         os.close(pout[PIPE_WRITE])
         os.close(perr[PIPE_READ])
         os.close(perr[PIPE_WRITE])

         try:
            #sleep(5)
            os.execv(pgm, parms)
         except OSError as e:
            print("The OS Error was:\n"+e.strerror+'\n')
            print("SAS Connection failed. No connection established. Double check you settings in sascfg.py file.\n")
            print("Attempted to run program "+pgm+" with the following parameters:"+str(parms)+"\n")
            print("If no OS Error above, try running the following command (where saspy is running) manually to see what is wrong:\n"+s+"\n")
            os._exit(-6)
         except:
            print("Subprocess failed to start. Double check you settings in sascfg.py file.\n")
            os._exit(-6)

      self.pid    = pidpty[0]
      self.stdin  = os.fdopen(pin[PIPE_WRITE], mode='wb')
      self.stderr = os.fdopen(perr[PIPE_READ], mode='rb')
      self.stdout = os.fdopen(pout[PIPE_READ], mode='rb')

      fcntl.fcntl(self.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
      fcntl.fcntl(self.stderr, fcntl.F_SETFL, os.O_NONBLOCK)

      rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
      if rc != None:
         self.pid = None
         lst = self.stdout.read1(4096)
         print("stdout from subprocess is:\n"+lst.decode()) 
         
      if self.pid is None:
         print("SAS Connection failed. No connection established. Double check you settings in sascfg.py file.\n")
         print("Attempted to run program "+pgm+" with the following parameters:"+str(parms)+"\n")
         print("Try running the following command (where saspy is running) manually to see if you can get more information on what went wrong:\n"+s+"\n")
         return NULL
      else:
         self.submit("options svgtitle='svgtitle'; options validvarname=any; ods graphics on;", "text")
         if self.pid is None:
            print("SAS Connection failed. No connection established. Double check you settings in sascfg.py file.\n")
            print("Attempted to run program "+pgm+" with the following parameters:"+str(parms)+"\n")
            print("Try running the following command (where saspy is running) manually to see if you can get more information on what went wrong:\n"+s+"\n")
            return None

      if self.sascfg.verbose:
         print("SAS Connection established. Subprocess id is "+str(self.pid)+"\n")
      return self.pid
コード例 #35
0
    def _get_startup(self):

        """
        get startup information based on new vimrc
        :return:
        """

        vimrc_new_path = os.path.join(self.working_path, 'vimrc')

        # get valid plugins
        valid_plugins = []
        with self.status_lock:
            for i, p in enumerate(self.all_plugins):
                if self.plugin_statuses[i]:
                    valid_plugins.append('Plugin ' + p)

        # create process to open vim using --startuptime
        with self.startup_lock:
            with open(self.vimrc_path, 'r') as vimrc_orig:
                with open(vimrc_new_path, 'w') as vimrc_new:
                    for line in vimrc_orig:
                        if line.startswith('Plugin') and line.rstrip() not in valid_plugins:
                            continue
                        else:
                            vimrc_new.write(line)
            startup_file_path = os.path.join(self.working_path, 'startup.log')
            vim_command = 'vim -u ' + vimrc_new_path + ' --startuptime ' + startup_file_path
            args = ['gnome-terminal', '-e', vim_command]
            proc = subprocess.Popen(args).pid
            os.waitid(os.P_PID, int(proc), os.WEXITED)

            # check if startup file successfully made
            while not os.path.exists(startup_file_path):
                pass
            while True:
                with open(startup_file_path, 'r') as startup_file:
                    for line in startup_file:
                        pass
                    if 'VIM STARTED' in line:
                        total_elapsed_time = line
                        break
            proc = (subprocess.Popen(['pgrep', '-f', vim_command[:7]],
                                     stdout=subprocess.PIPE)
                              .stdout.read().decode('utf-8').rstrip())
            os.kill(int(proc), 9)
            swap_file_path = os.path.join(self.working_path, '.swp')
            try:
                os.remove(swap_file_path)
            except OSError:
                pass

            # gather source info from startuptime file
            source_times = []
            with open(startup_file_path, 'r') as startup_file:
                for line in startup_file:
                    logging.debug(line.rsplit(' '))
                    try:
                        float(line.rsplit(' ')[2])
                    except (ValueError, IndexError):
                        continue
                    source_times.append(line)

            # sort and place info into analysis queue
            source_times.sort(key=lambda s_line: float(s_line.split(' ')[2]),
                              reverse=True)
            source_times.insert(0, total_elapsed_time)
            self.analysis_queue.put(source_times)
            self.analysis_event.set()
            os.remove(vimrc_new_path)
            os.remove(startup_file_path)
コード例 #36
0
ファイル: sasiostdio.py プロジェクト: metllord/saspy
   def _breakprompt(self, eos):
        found = False
        logf  = ''
        lstf  = ''
        bc    = False

        if self.pid is None:
            return dict(LOG="No SAS process attached. SAS process has terminated unexpectedly.", LST='', ABORT=True)

        if self.sascfg.ssh:
           response = self.sascfg._prompt(
                     "SAS attention handling not supported over ssh. Please enter (T) to terminate SAS or (C) to continue.")
           while True:
              if response.upper() == 'C':
                 return dict(LOG='', LST='', BC=True)
              if response.upper() == 'T':
                 break
              response = self.sascfg._prompt("Please enter (T) to terminate SAS or (C) to continue.")
              
        interrupt = signal.SIGINT
        os.kill(self.pid, interrupt)
        sleep(.25)

        while True:
            rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
            if rc is not None:
                self.pid = None
                outrc = str(rc)
                return dict(LOG='SAS process has terminated unexpectedly. Pid State= ' +
                            outrc, LST='',ABORT=True)

            lst = self.stdout.read1(4096).decode(self.sascfg.encoding)
            lstf += lst
            if len(lst) > 0:
                lsts = lst.rpartition('Select:')
                if lsts[0] != '' and lsts[1] != '':
                    found = True
                    query = lsts[1] + lsts[2].rsplit('\n?')[0] + '\n'
                    print('Processing interrupt\nAttn handler Query is\n\n' + query)
                    response = self.sascfg._prompt("Please enter your Response: ")
                    self.stdin.write(response.encode(self.sascfg.encoding) + b'\n')
                    self.stdin.flush()
                    if (response == 'C' or response == 'c') and query.count("C. Cancel") >= 1:
                       bc = True
                       break
                else:
                    lsts = lst.rpartition('Press')
                    if lsts[0] != '' and lsts[1] != '':
                        query = lsts[1] + lsts[2].rsplit('\n?')[0] + '\n'
                        print('Secondary Query is:\n\n' + query)
                        response = self.sascfg._prompt("Please enter your Response: ")
                        self.stdin.write(response.encode(self.sascfg.encoding) + b'\n')
                        self.stdin.flush()
                        if (response == 'N' or response == 'n') and query.count("N to continue") >= 1:
                           bc = True
                           break
                    else:
                        #print("******************No 'Select' or 'Press' found in lst=")
                        pass
            else:
                log = self.stderr.read1(4096).decode(self.sascfg.encoding)
                logf += log
                self._log += log

                if log.count(eos) >= 1:
                    print("******************Found end of step. No interrupt processed")
                    found = True

                if found:
                    break

            sleep(.25)

        lstr = lstf
        logr = logf

        return dict(LOG=logr, LST=lstr, BC=bc)
コード例 #37
0
 def sync_wait_reapable(pid):
     waitid(os.P_PID, pid, os.WEXITED | os.WNOWAIT)
コード例 #38
0
ファイル: expect.py プロジェクト: lilydjwg/winterpy
 def _interact_leave(self, signum, sigframe):
   while os.waitid(os.P_ALL, 0, os.WEXITED | os.WNOHANG) is not None:
     pass
コード例 #39
0
ファイル: portfolio.py プロジェクト: flammel/vvt
p_bmc_r, p_bmc_w = os.pipe()
os.set_inheritable(p_bmc_r,True)
id_bmc=os.fork()
if id_bmc==0:
    sys.stdin.close()
    os.dup2(p_bmc_r, 0)
    os.execl(binpath+'vvt-bmc','vvt-bmc','--solver='+binpath+'z3 -smt2 -in','-i','-d','50')
os.close(p_bmc_r)
    
while True:
    inp = sys.stdin.buffer.read(1024)
    if len(inp)==0:
        os.close(p_ic3_w)
        os.close(p_bmc_w)
        break
    os.write(p_ic3_w,inp)
    os.write(p_bmc_w,inp)
    
id_exit,res = os.wait()

if id_exit==id_ic3:
    if res==0:
        os.kill(id_bmc,signal.SIGKILL)
    else:
        os.waitid(os.P_PID,id_bmc,os.WEXITED)
else:
    if res==0:
        os.kill(id_ic3,signal.SIGKILL)
    else:
        os.waitid(os.P_PID,id_ic3,os.WEXITED)
コード例 #40
0
ファイル: shell.py プロジェクト: bkidwell/ebmeta
def save_output(args, output_file):
    """Run args[0] with arguments args[1:] and save standard output to output_file."""

    with open(output_file, 'w', encoding='utf-8') as f:
        p = subprocess.Popen(args, stfout=f)
        os.waitid(p.pid, 0)
コード例 #41
0
     #status = os.system("python preprocess.py -train_src data/src-train.txt -train_tgt data/tgt-train.txt -valid_src data/src-val.txt -valid_tgt data/tgt-val.txt -save_data data/corpus")
     #if (status != 0):
     #sys.exit(1)
     os.environ["CUDA_VISIBLE_DEVICES"] = "0"
     status = os.system(
         "./train.py -data data/corpus -save_model corpus_model -world_size 1 -gpu_ranks 0 -batch_size "
         + str(args.onmt_batch) +
         " -seed 1  -log_file omnt.log -train_steps " +
         str(args.onmt_steps) + " -valid_steps " +
         str(args.onmt_valid_steps))
     if (status != 0):
         sys.exit(1)
     #sys.exit(0)
 else:
     #wait for processes to exit
     res1 = os.waitid(os.P_PID, pid_summarunner, os.WEXITED)
     res2 = os.waitid(os.P_PID, pid_opennmt, os.WEXITED)
     print(str(res1.si_status) + " " + str(res2.si_status))
     log.write("Training finished, ")
     if ((res1.si_status == 0) & (res2.si_status == 0)):
         log.write("no erros encountered\n")
         log.close()
         sys.exit(0)
     elif ((res1.si_status != 0) & (res2.si_status == 0)):
         log.write("SummaRuNNer finished with error\n")
         log.close()
         sys.exit(1)
     elif ((res1.si_status == 0) & (res2.si_status != 0)):
         log.write("OpenNMT finished with error\n")
         log.close()
         sys.exit(1)
コード例 #42
0
    def _breakprompt(self, eos):
        found = False
        logf = ''
        lstf = ''
        bc = False

        if self.pid is None:
            return dict(
                LOG=
                b"No SAS process attached. SAS process has terminated unexpectedly.",
                LST=b'',
                ABORT=True)

        interrupt = signal.SIGINT
        os.kill(self.pid, interrupt)
        sleep(.25)

        while True:
            rc = os.waitid(os.P_PID, self.pid, os.WEXITED | os.WNOHANG)
            if rc is not None:
                self.pid = None
                outrc = str(rc)
                return dict(
                    LOG=b'SAS process has terminated unexpectedly. Pid State= '
                    + outrc.encode(),
                    LST=b'',
                    ABORT=True)

            lst = self.stdout.read1(4096).decode()
            lstf += lst
            if len(lst) > 0:
                lsts = lst.rpartition('Select:')
                if lsts[0] != '' and lsts[1] != '':
                    found = True
                    query = lsts[1] + lsts[2].rsplit('\n?')[0] + '\n'
                    print('Processing interrupt\nAttn handler Query is\n\n' +
                          query)
                    response = self.sascfg._prompt(
                        "Please enter your Response: ")
                    self.stdin.write(response.encode() + b'\n')
                    self.stdin.flush()
                    if (response == 'C' or response
                            == 'c') and query.count("C. Cancel") >= 1:
                        bc = True
                        break
                else:
                    lsts = lst.rpartition('Press')
                    if lsts[0] != '' and lsts[1] != '':
                        query = lsts[1] + lsts[2].rsplit('\n?')[0] + '\n'
                        print('Secondary Query is:\n\n' + query)
                        response = self.sascfg._prompt(
                            "Please enter your Response: ")
                        self.stdin.write(response.encode() + b'\n')
                        self.stdin.flush()
                        if (response == 'N' or response
                                == 'n') and query.count("N to continue") >= 1:
                            bc = True
                            break
                    else:
                        #print("******************No 'Select' or 'Press' found in lst=")
                        pass
            else:
                log = self.stderr.read1(4096).decode()
                logf += log
                self._log += log

                if log.count(eos) >= 1:
                    print(
                        "******************Found end of step. No interrupt processed"
                    )
                    found = True

                if found:
                    break

            sleep(.25)

        lstr = lstf
        logr = logf

        return dict(LOG=logr, LST=lstr, BC=bc)
コード例 #43
0
ファイル: epoll-demo.py プロジェクト: zyga/python-glibc
def main():
    # Block signals so that they aren't handled
    # according to their default dispositions
    mask = sigset_t()
    fdsi = signalfd_siginfo()
    sigemptyset(mask)
    sigaddset(mask, SIGINT)
    sigaddset(mask, SIGQUIT)
    sigaddset(mask, SIGCHLD)
    sigaddset(mask, SIGPIPE)
    print("Blocking signals")
    sigprocmask(SIG_BLOCK, mask, None)
    # Get a signalfd descriptor
    sfd = signalfd(-1, mask, SFD_CLOEXEC | SFD_NONBLOCK)
    print("Got signalfd", sfd)
    # Get a epoll descriptor
    ep = epoll()
    print("Got epollfd", ep.fileno())
    print("Adding signalfd fd {} to epoll".format(sfd))
    ep.register(sfd, EPOLLIN)
    # Get two pair of pipes, one for stdout and one for stderr
    stdout_pair = (c_int * 2)()
    pipe2(byref(stdout_pair), O_CLOEXEC | O_NONBLOCK)
    print("Got stdout pipe pair", stdout_pair[0], stdout_pair[1])
    print("Adding pipe fd {} to epoll".format(stdout_pair[0]))
    ep.register(stdout_pair[0], EPOLLIN)
    stderr_pair = (c_int * 2)()
    pipe2(byref(stderr_pair), O_CLOEXEC | O_NONBLOCK)
    print("Got stderr pipe pair", stderr_pair[0], stderr_pair[1])
    print("Adding pipe fd {} to epoll".format(stdout_pair[0]))
    ep.register(stderr_pair[0], EPOLLIN)
    prog = argv[1:]
    if not prog:
        prog = ['echo', 'usage: demo.py PROG [ARGS]']
    print("Going to start program:", prog)
    # Fork :-)
    pid = fork()
    if pid == 0:  # Child.
        # NOTE: we are not closing any of the pipe ends. Why? Because they are
        # all O_CLOEXEC and will thus not live across the execlp call down
        # below.
        dup3(stdout_pair[1], 1, 0)
        dup3(stderr_pair[1], 2, 0)
        execlp(prog[0], *prog)
        return -1
    else:
        close(stdout_pair[1])
        close(stderr_pair[1])
    with fdopen(sfd, 'rb', 0) as sfd_stream:
        waiting_for = set(['stdout', 'stderr', 'proc'])
        while waiting_for:
            print("Waiting for events...", ' '.join(waiting_for), flush=True)
            event_list = ep.poll(maxevents=10)
            print("epoll_wait() read {} events".format(len(event_list)))
            for fd, events in event_list:
                print("[event]")
                event_bits = []
                if events & EPOLLIN == EPOLLIN:
                    event_bits.append('EPOLLIN')
                if events & EPOLLOUT == EPOLLOUT:
                    event_bits.append('EPOLLOUT')
                if events & EPOLLRDHUP == EPOLLRDHUP:
                    event_bits.append('EPOLLRDHUP')
                if events & EPOLLPRI == EPOLLPRI:
                    event_bits.append('EPOLLPRI')
                if events & EPOLLERR == EPOLLERR:
                    event_bits.append('EPOLLERR')
                if events & EPOLLHUP == EPOLLHUP:
                    event_bits.append('EPOLLHUP')
                if fd == sfd:
                    fd_name = 'signalfd()'
                elif fd == stdout_pair[0]:
                    fd_name = 'stdout pipe2()'
                elif fd == stderr_pair[0]:
                    fd_name = 'stderr pipe2()'
                else:
                    fd_name = "???"
                print(" events: {} ({})".format(
                    events, ' | '.join(event_bits)))
                print(" fd: {} ({})".format(fd, fd_name))
                if fd == sfd:
                    print("signalfd() descriptor ready")
                    if events & EPOLLIN:
                        print("Reading data from signalfd()...")
                        # Read the next delivered signal
                        sfd_stream.readinto(fdsi)
                        if fdsi.ssi_signo == SIGINT:
                            print("Got SIGINT")
                        elif fdsi.ssi_signo == SIGQUIT:
                            print("Got SIGQUIT")
                            raise SystemExit("exiting prematurly")
                        elif fdsi.ssi_signo == SIGCHLD:
                            print("Got SIGCHLD")
                            waitid_result = waitid(
                                P_PID, pid,
                                WNOHANG |
                                WEXITED | WSTOPPED | WCONTINUED |
                                WUNTRACED)
                            if waitid_result is None:
                                print("child not ready")
                            else:
                                print("child event")
                                print("si_pid:", waitid_result.si_pid)
                                print("si_uid:", waitid_result.si_uid)
                                print("si_signo:", waitid_result.si_signo)
                                assert waitid_result.si_signo == SIGCHLD
                                print("si_status:", waitid_result.si_status)
                                print("si_code:", waitid_result.si_code)
                                if waitid_result.si_code == CLD_EXITED:
                                    # assert WIFEXITED(waitid_result.si_status)
                                    print("child exited normally")
                                    print("exit code:",
                                          WEXITSTATUS(waitid_result.si_status))
                                    waiting_for.remove('proc')
                                    if 'stdout' in waiting_for:
                                        ep.unregister(stdout_pair[0])
                                        close(stdout_pair[0])
                                        waiting_for.remove('stdout')
                                    if 'stderr' in waiting_for:
                                        ep.unregister(stderr_pair[0])
                                        close(stderr_pair[0])
                                        waiting_for.remove('stderr')
                                elif waitid_result.si_code == CLD_KILLED:
                                    assert WIFSIGNALED(waitid_result.si_status)
                                    print("child was killed by signal")
                                    print("death signal:",
                                          waitid_result.si_status)
                                    waiting_for.remove('proc')
                                elif waitid_result.si_code == CLD_DUMPED:
                                    assert WIFSIGNALED(waitid_result.si_status)
                                    print("core:",
                                          WCOREDUMP(waitid_result.si_status))
                                elif waitid_result.si_code == CLD_STOPPED:
                                    print("child was stopped")
                                    print("stop signal:",
                                          waitid_result.si_status)
                                elif waitid_result.si_code == CLD_TRAPPED:
                                    print("child was trapped")
                                    # TODO: we could explore trap stuff here
                                elif waitid_result.si_code == CLD_CONTINUED:
                                    print("child was continued")
                                else:
                                    raise SystemExit(
                                        "Unknown CLD_ code: {}".format(
                                            waitid_result.si_code))
                        elif fdsi.ssi_signo == SIGPIPE:
                            print("Got SIGPIPE")
                        else:
                            print("Read unexpected signal: {}".format(
                                fdsi.ssi_signo))
                elif fd == stdout_pair[0]:
                    print("pipe() (stdout) descriptor ready")
                    if events & EPOLLIN:
                        print("Reading data from stdout...")
                        data = read(stdout_pair[0], PIPE_BUF)
                        print("Read {} bytes from stdout".format(len(data)))
                        print(data)
                    if events & EPOLLHUP:
                        print("Removing stdout pipe from epoll")
                        ep.unregister(stdout_pair[0])
                        print("Closing stdout pipe")
                        close(stdout_pair[0])
                        waiting_for.remove('stdout')
                elif fd == stderr_pair[0]:
                    print("pipe() (stderr) descriptor ready")
                    if events & EPOLLIN:
                        print("Reading data from stdout...")
                        data = read(stderr_pair[0], PIPE_BUF)
                        print("Read {} bytes from stderr".format(len(data)))
                        print(data)
                    if events & EPOLLHUP:
                        print("Removing stderr pipe from epoll")
                        ep.unregister(stderr_pair[0])
                        print("Closing stderr pipe")
                        close(stderr_pair[0])
                        waiting_for.remove('stderr')
                else:
                    # FIXME: we are still getting weird activation events on fd
                    # 0 (stdin) with events == 0 (nothing). I cannot explain
                    # this yet.
                    print("Unexpected descriptor ready:", fd)
    assert not waiting_for
    print("Closing", ep)
    ep.close()
    print("Unblocking signals")
    sigprocmask(SIG_UNBLOCK, mask, None)
    print("Exiting normally")
コード例 #44
0
ファイル: portfolio.py プロジェクト: mschlaipfer/vvt
os.set_inheritable(p_bmc_r, True)
id_bmc = os.fork()
if id_bmc == 0:
    sys.stdin.close()
    os.dup2(p_bmc_r, 0)
    os.execl(binpath + 'vvt-bmc', 'vvt-bmc',
             '--solver=' + binpath + 'z3 -smt2 -in', '-i', '-d', '50')
os.close(p_bmc_r)

while True:
    inp = sys.stdin.buffer.read(1024)
    if len(inp) == 0:
        os.close(p_ic3_w)
        os.close(p_bmc_w)
        break
    os.write(p_ic3_w, inp)
    os.write(p_bmc_w, inp)

id_exit, res = os.wait()

if id_exit == id_ic3:
    if res == 0:
        os.kill(id_bmc, signal.SIGKILL)
    else:
        os.waitid(os.P_PID, id_bmc, os.WEXITED)
else:
    if res == 0:
        os.kill(id_ic3, signal.SIGKILL)
    else:
        os.waitid(os.P_PID, id_ic3, os.WEXITED)
コード例 #45
0
def main():
    with ExitStack() as stack:
        # Block signals so that they aren't handled according to their default
        # dispositions until after this block is terminated, or, in our case,
        # never since we also use signalfd to collect them.
        print("Blocking signals...")
        stack.enter_context(pthread_sigmask([SIGCHLD]))
        print("Setting up epoll...")
        es = EpollSelector()
        print("Got", es)
        print("Setting up signalfd...")
        sfd_obj = stack.enter_context(
            signalfd([SIGCHLD], SFD_CLOEXEC | SFD_NONBLOCK))
        print("Got", sfd_obj)
        print("Adding signalfd epoll...")
        es.register(sfd_obj, EVENT_READ, 'signalfd(2)')
        print("Setting up stdout pipe...")
        stdout_pair = pipe2(O_CLOEXEC | O_NONBLOCK)
        print("Got", stdout_pair)
        print("Adding stdout pipe to epoll...")
        es.register(stdout_pair[0], EVENT_READ, 'stdout')
        print("Getting stderr pipe...")
        stderr_pair = pipe2(O_CLOEXEC | O_NONBLOCK)
        print("Got", stderr_pair)
        print("Adding stderr pipe to epoll...")
        es.register(stderr_pair[0], EVENT_READ, 'stderr')
        prog = argv[1:]
        if not prog:
            prog = ['echo', 'usage: demo.py PROG [ARGS]']
        print("Going to start program:", prog)
        # Fork :-)
        pid = fork()
        if pid == 0:  # Child.
            # NOTE: we are not closing any of the pipe ends. Why? Because they
            # are all O_CLOEXEC and will thus not live across the execlp call
            # down below.
            dup3(stdout_pair[1], 1, 0)
            dup3(stderr_pair[1], 2, 0)
            execlp(prog[0], *prog)
            return -1
        else:
            close(stdout_pair[1])
            close(stderr_pair[1])
        waiting_for = set(['stdout', 'stderr', 'proc'])
        while waiting_for:
            print("Waiting for events...", ' '.join(waiting_for), flush=True)
            event_list = es.select()
            print("EpollSelector.select() read {} events".format(
                len(event_list)))
            for key, events in event_list:
                print("[event]")
                print(" key: {!r}".format(key))
                print(" events: {!r}".format(events))
                if key.fd == sfd_obj.fileno():
                    print("signalfd() descriptor ready")
                    if events & EVENT_READ:
                        print("Reading data from signalfd()...")
                        # Read the next delivered signal
                        try:
                            fdsi = sfd_obj.read()[0]
                        except IndexError:
                            continue
                        if fdsi.ssi_signo == SIGINT:
                            print("Got SIGINT")
                        elif fdsi.ssi_signo == SIGQUIT:
                            print("Got SIGQUIT")
                            raise SystemExit("exiting prematurly")
                        elif fdsi.ssi_signo == SIGCHLD:
                            print("Got SIGCHLD")
                            waitid_result = waitid(
                                P_PID, pid,
                                WNOHANG |
                                WEXITED | WSTOPPED | WCONTINUED |
                                WUNTRACED)
                            if waitid_result is None:
                                print("child not ready")
                            else:
                                print("child event")
                                print("si_pid:", waitid_result.si_pid)
                                print("si_uid:", waitid_result.si_uid)
                                print("si_signo:", waitid_result.si_signo)
                                assert waitid_result.si_signo == SIGCHLD
                                print("si_status:", waitid_result.si_status)
                                print("si_code:", waitid_result.si_code)
                                if waitid_result.si_code == CLD_EXITED:
                                    # assert WIFEXITED(waitid_result.si_status)
                                    print("child exited normally")
                                    print("exit code:",
                                          WEXITSTATUS(waitid_result.si_status))
                                    waiting_for.remove('proc')
                                    if 'stdout' in waiting_for:
                                        es.unregister(stdout_pair[0])
                                        close(stdout_pair[0])
                                        waiting_for.remove('stdout')
                                    if 'stderr' in waiting_for:
                                        es.unregister(stderr_pair[0])
                                        close(stderr_pair[0])
                                        waiting_for.remove('stderr')
                                elif waitid_result.si_code == CLD_KILLED:
                                    assert WIFSIGNALED(waitid_result.si_status)
                                    print("child was killed by signal")
                                    print("death signal:",
                                          waitid_result.si_status)
                                    waiting_for.remove('proc')
                                elif waitid_result.si_code == CLD_DUMPED:
                                    assert WIFSIGNALED(waitid_result.si_status)
                                    print("core:",
                                          WCOREDUMP(waitid_result.si_status))
                                elif waitid_result.si_code == CLD_STOPPED:
                                    print("child was stopped")
                                    print("stop signal:",
                                          waitid_result.si_status)
                                elif waitid_result.si_code == CLD_TRAPPED:
                                    print("child was trapped")
                                    # TODO: we could explore trap stuff here
                                elif waitid_result.si_code == CLD_CONTINUED:
                                    print("child was continued")
                                else:
                                    raise SystemExit(
                                        "Unknown CLD_ code: {}".format(
                                            waitid_result.si_code))
                        elif fdsi.ssi_signo == SIGPIPE:
                            print("Got SIGPIPE")
                        else:
                            print("Read unexpected signal: {}".format(
                                fdsi.ssi_signo))
                elif key.fd in (stdout_pair[0], stderr_pair[0]):
                    print("{} pipe() descriptor ready".format(key.data))
                    if events & EVENT_READ:
                        print("Reading data from {} pipe...".format(key.data))
                        data = read(key.fd, PIPE_BUF)
                        print("Read {} bytes from {} pipe".format(
                            len(data), key.data))
                        print("Data:", data)
                        if len(data) == 0:
                            print("Removing {} pipe from EpollSelector".format(
                                key.data))
                            es.unregister(key.fd)
                            print("Closing pipe")
                            close(key.fd)
                            waiting_for.remove(key.data)
                else:
                    # FIXME: we are still getting weird activation events on fd
                    # 0 (stdin) with events == 0 (nothing). I cannot explain
                    # this yet.
                    print("Unexpected descriptor ready:", key.fd)
    assert not waiting_for