'Perform extended validation on the executable path, argv, and envp.
Mostly to make Python happy, but also to prevent common pitfalls.'

def _validate(self, cwd, executable, argv, env):

    cwd = (cwd or os.path.curdir)
    if isinstance(argv, (str, unicode)):
        argv = [argv]
    if (not all((isinstance(arg, (str, unicode)) for arg in argv))):
        self.error(('argv    must    be    strings:    %r' % argv))
    argv = list((argv or []))
    for (i, arg) in enumerate(argv):
        if ('\x00' in arg[:(-1)]):
            self.error(('Inappropriate    nulls    in    argv[%i]:    %r' % (i, arg)))
        argv[i] = arg.rstrip('\x00')
    if (not executable):
        if (not argv):
            self.error('Must    specify    argv    or    executable')
        executable = argv[0]
    if executable.startswith(os.path.sep):
        pass
    elif ((os.path.sep not in executable) and which(executable)):
        executable = which(executable)
    elif (os.path.sep not in executable):
        tmp = executable
        executable = os.path.join(cwd, executable)
        self.warn_once(('Could    not    find    executable    %r    in    $PATH,    using    %r    instead' % (tmp, executable)))
    if (not os.path.exists(executable)):
        self.error(('%r    does    not    exist' % executable))
    if (not os.path.isfile(executable)):
        self.error(('%r    is    not    a    file' % executable))
    if (not os.access(executable, os.X_OK)):
        self.error(('%r    is    not    marked    as    executable    (+x)' % executable))
    env = dict((os.environ if (env is None) else env))
    for (k, v) in env.items():
        if (not isinstance(k, (str, unicode))):
            self.error(('Environment    keys    must    be    strings:    %r' % k))
        if (not isinstance(k, (str, unicode))):
            self.error(('Environment    values    must    be    strings:    %r=%r' % (k, v)))
        if ('\x00' in k[:(-1)]):
            self.error(('Inappropriate    nulls    in    env    key:    %r' % k))
        if ('\x00' in v[:(-1)]):
            self.error(('Inappropriate    nulls    in    env    value:    %r=%r' % (k, v)))
        env[k.rstrip('\x00')] = v.rstrip('\x00')
    return (executable, argv, env)
