'Start the subprocess.  It must not be running already.
Return the process id.  If the fork() call fails, return None.'

def spawn(self):

    options = self.config.options
    if self.pid:
        msg = ('process    %r    already    running' % self.config.name)
        options.logger.warn(msg)
        return
    self.killing = False
    self.spawnerr = None
    self.exitstatus = None
    self.system_stop = False
    self.administrative_stop = False
    self.laststart = time.time()
    self._assertInState(ProcessStates.EXITED, ProcessStates.FATAL, ProcessStates.BACKOFF, ProcessStates.STOPPED)
    self.change_state(ProcessStates.STARTING)
    try:
        (filename, argv) = self.get_execv_args()
    except ProcessException as what:
        self.record_spawnerr(what.args[0])
        self._assertInState(ProcessStates.STARTING)
        self.change_state(ProcessStates.BACKOFF)
        return
    try:
        (self.dispatchers, self.pipes) = self.config.make_dispatchers(self)
    except (OSError, IOError) as why:
        code = why.args[0]
        if (code == errno.EMFILE):
            msg = ('too    many    open    files    to    spawn    %r' % self.config.name)
        else:
            msg = ('unknown    error    making    dispatchers    for    %r:    %s' % (self.config.name, errno.errorcode.get(code, code)))
        self.record_spawnerr(msg)
        self._assertInState(ProcessStates.STARTING)
        self.change_state(ProcessStates.BACKOFF)
        return
    try:
        pid = options.fork()
    except OSError as why:
        code = why.args[0]
        if (code == errno.EAGAIN):
            msg = ('Too    many    processes    in    process    table    to    spawn    %r' % self.config.name)
        else:
            msg = ('unknown    error    during    fork    for    %r:    %s' % (self.config.name, errno.errorcode.get(code, code)))
        self.record_spawnerr(msg)
        self._assertInState(ProcessStates.STARTING)
        self.change_state(ProcessStates.BACKOFF)
        options.close_parent_pipes(self.pipes)
        options.close_child_pipes(self.pipes)
        return
    if (pid != 0):
        return self._spawn_as_parent(pid)
    else:
        return self._spawn_as_child(filename, argv)
