Ejemplo n.º 1
0
 def process(self):
     assert not self.closed
     assert self.queue
     conn = self.queue[0]
     if len(self.queue) > 1:
         self.log('queued request, qlen=%s' % len(self.queue))
     # Try to read the single byte written by the child.
     # This can fail if the child died or the pipe really
     # wasn't ready (select returns a hint only).  The fd has
     # been made non-blocking by spawn_child.
     try:
         ready_byte = os.read(self.fd, 1)
         if not ready_byte:
             raise IOError('null read from child')
         assert ready_byte == b'1', repr(ready_byte)
     except (OSError, IOError) as exc:
         if exc.errno == errno.EWOULDBLOCK:
             # select was wrong and fd not ready.  Child might
             # still be busy so keep it alive (don't close).
             return
         self.log('error while getting child status: %s' % exc)
     else:
         try:
             passfd.sendfd(self.fd, conn.fileno())
         except IOError as exc:
             if exc.errno == errno.EPIPE:
                 # broken pipe, child died?
                 self.log('EPIPE passing fd to child')
             else:
                 # some other error that we don't expect
                 self.log('IOError passing fd to child: %s' % exc.errno)
         else:
             # fd was apparently passed okay to the child.
             # The child could die before completing the
             # request but that's not our problem anymore.
             self.last_used = time.time()
             conn.close()
             del self.queue[0]
             return
     # We have failed to pass the fd to the child.  Since the
     # child is not behaving how we expect, we close 'fd'.  That
     # will cause the child to die (if it hasn't already).  We will
     # reap the exit status in reap_children() and remove the Child()
     # object from the 'children' list.
     self.close()
Ejemplo n.º 2
0
 def process(self, conn):
     # Try to read the single byte written by the child.
     # This can fail if the child died or the socket really
     # wasn't ready (select returns a hint only).  The fd has
     # been made non-blocking by spawn_child.
     try:
         ready_byte = os.read(self.fd, 1)
         if not ready_byte:
             raise IOError('null read from child')
         assert ready_byte == b"1", repr(ready_byte)
     except (OSError, IOError) as exc:
         if exc.errno == errno.EWOULDBLOCK:
             # select was wrong and fd not ready.  Child might
             # still be busy so keep it alive (don't close).
             return False
         else:
             self.log('error while getting child status: %s' % exc)
     else:
         # The byte was read okay, now we need to pass the fd
         # of the request to the child.  This can also fail
         # if the child died.  Again, if this fails we fall
         # through to the "reap_children" logic and will
         # retry the select call.
         try:
             passfd.sendfd(self.fd, conn.fileno())
         except IOError as exc:
             if exc.errno == errno.EPIPE:
                 # broken pipe, child died?
                 self.log('EPIPE passing fd to child')
             else:
                 # some other error that we don't expect
                 self.log('IOError passing fd to child: %s' % exc.errno)
         else:
             # fd was apparently passed okay to the child.
             # The child could die before completing the
             # request but that's not our problem anymore.
             return True
     # We have failed to pass the fd to the child.  Since the
     # child is not behaving how we expect, we close 'fd'.  That
     # will cause the child to die (if it hasn't already).  We will
     # reap the exit status in reap_children() and remove the Child()
     # object from the 'children' list.
     self.close()
     return False  # did not pass fd successfully
Ejemplo n.º 3
0
                    assert ready_byte == "1", repr(ready_byte)
                except socket.error, exc:
                    if exc[0] == errno.EWOULDBLOCK:
                        pass  # select was wrong
                    else:
                        raise
                except (OSError, IOError):
                    pass  # child died?
                else:
                    # The byte was read okay, now we need to pass the fd
                    # of the request to the child.  This can also fail
                    # if the child died.  Again, if this fails we fall
                    # through to the "reap_children" logic and will
                    # retry the select call.
                    try:
                        passfd.sendfd(child.fd, conn.fileno())
                    except IOError, exc:
                        if exc.errno == errno.EPIPE:
                            pass  # broken pipe, child died?
                        else:
                            raise
                    else:
                        # fd was apparently passed okay to the child.
                        # The child could die before completing the
                        # request but that's not our problem anymore.
                        return

            # didn't find any child, check if any died
            self.reap_children()

            # start more children if we haven't met max_children limit
Ejemplo n.º 4
0
                    assert ready_byte == "1", repr(ready_byte)
                except socket.error, exc:
                    if exc[0]  == errno.EWOULDBLOCK:
                        pass # select was wrong
                    else:
                        raise
                except (OSError, IOError):
                    pass # child died?
                else:
                    # The byte was read okay, now we need to pass the fd
                    # of the request to the child.  This can also fail
                    # if the child died.  Again, if this fails we fall
                    # through to the "reap_children" logic and will
                    # retry the select call.
                    try:
                        passfd.sendfd(child.fd, conn.fileno())
                    except IOError, exc:
                        if exc.errno == errno.EPIPE:
                            pass # broken pipe, child died?
                        else:
                            raise
                    else:
                        # fd was apparently passed okay to the child.
                        # The child could die before completing the
                        # request but that's not our problem anymore.
                        return

            # didn't find any child, check if any died
            self.reap_children()

            # start more children if we haven't met max_children limit
Ejemplo n.º 5
0
#
# fork() off!
#

pid = os.fork()

if pid != 0:
    # We're in the parent.

    # ioctl() will only pass raw filedescriptors. Find fd of fileObj.
    fd = fileObj.fileno()

    # Send to the child
    os.write(wfd, b'x')
    passfd.sendfd(wfd, fd)

    # Wait for child to terminate, then exit.
    os.waitpid(pid, 0)
    fileObj.close()
    sys.exit(0)

else:
    # We're in the child.

    fileObj.close()
    
    print(os.read(rfd, 1))
    fd = passfd.recvfd(rfd)

    # Reopen the filedescriptor as a Python File-object.