'Spawn an operating-system process.
This is where the hard work of disconnecting all currently open
files / forking / executing the new process happens.  (This is
executed automatically when a Process is instantiated.)
This will also run the subprocess as a given user ID and group ID, if
specified.  (Implementation Note: this doesn\'t support all the arcane
nuances of setXXuid on UNIX: it will assume that either your effective
or real UID is 0.)'

def __init__(self, reactor, executable, args, environment, path, proto, uid=None, gid=None, childFDs=None):

    if (not proto):
        assert ('r' not in childFDs.values())
        assert ('w' not in childFDs.values())
    _BaseProcess.__init__(self, proto)
    self.pipes = {}
    helpers = {}
    if (childFDs is None):
        childFDs = {0: 'w', 1: 'r', 2: 'r'}
    debug = self.debug
    if debug:
        print('childFDs', childFDs)
    _openedPipes = []
    def pipe():
        (r, w) = os.pipe()
        _openedPipes.extend([r, w])
        return (r, w)
    fdmap = {}
    try:
        for (childFD, target) in items(childFDs):
            if debug:
                print(('[%d]' % childFD), target)
            if (target == 'r'):
                (readFD, writeFD) = pipe()
                if debug:
                    print(('readFD=%d,    writeFD=%d' % (readFD, writeFD)))
                fdmap[childFD] = writeFD
                helpers[childFD] = readFD
            elif (target == 'w'):
                (readFD, writeFD) = pipe()
                if debug:
                    print(('readFD=%d,    writeFD=%d' % (readFD, writeFD)))
                fdmap[childFD] = readFD
                helpers[childFD] = writeFD
            else:
                assert (type(target) == int), ('%r    should    be    an    int' % (target,))
                fdmap[childFD] = target
        if debug:
            print('fdmap', fdmap)
        if debug:
            print('helpers', helpers)
        self._fork(path, uid, gid, executable, args, environment, fdmap=fdmap)
    except:
        for pipe in _openedPipes:
            os.close(pipe)
        raise
    self.proto = proto
    for (childFD, parentFD) in items(helpers):
        os.close(fdmap[childFD])
        if (childFDs[childFD] == 'r'):
            reader = self.processReaderFactory(reactor, self, childFD, parentFD)
            self.pipes[childFD] = reader
        if (childFDs[childFD] == 'w'):
            writer = self.processWriterFactory(reactor, self, childFD, parentFD, forceReadHack=True)
            self.pipes[childFD] = writer
    try:
        if (self.proto is not None):
            self.proto.makeConnection(self)
    except:
        log.err()
    registerReapProcessHandler(self.pid, self)
