Example #1
0
 def test_exit(self):
     try:
         import posix, _rawffi
     except ImportError:
         skip("requires posix.fork() to test")
     #
     pid = posix.fork()
     if pid == 0:
         _rawffi.exit(5)   # in the child
     pid, status = posix.waitpid(pid, 0)
     assert posix.WIFEXITED(status)
     assert posix.WEXITSTATUS(status) == 5
Example #2
0
    def Wait(self):
        # This is a list of async jobs
        while True:
            try:
                pid, status = posix.wait()
            except OSError as e:
                #log('wait() error: %s', e)
                if e.errno == errno.ECHILD:
                    return False  # nothing to wait for caller should stop
                elif e.errno == errno.EINTR:
                    # This happens when we register a handler for SIGINT, and thus never
                    # get the KeyboardInterrupt exception?  Not sure why.
                    # Try
                    # $ cat   # Now hit Ctrl-C
                    #log('Continuing')
                    continue  # try again
                else:
                    # An error we don't know about.
                    raise
            else:
                break  # no exception thrown, so no need to retry

        #log('WAIT got %s %s', pid, status)

        # TODO: change status in more cases.
        if posix.WIFSIGNALED(status):
            if posix.WTERMSIG(status) == signal.SIGINT:
                print()
        elif posix.WIFEXITED(status):
            status = posix.WEXITSTATUS(status)
            #log('exit status: %s', status)

        # This could happen via coding error.  But this may legitimately happen
        # if a grandchild outlives the child (its parent).  Then it is reparented
        # under this process, so we might receive notification of its exit, even
        # though we didn't start it.  We can't have any knowledge of such
        # processes, so print a warning.
        if pid not in self.callbacks:
            util.warn("PID %d stopped, but osh didn't start it", pid)
            return True  # caller should keep waiting

        callback = self.callbacks.pop(pid)
        callback(pid, status)
        self.last_status = status  # for wait -n

        return True  # caller should keep waiting