Пример #1
0
def posix_spawnp(filename, args, fileactions=None, env=None):
    """Invoke posix_spawnp(3C).

    'filename' is the name of the executeable file.

    'args' is a sequence of arguments supplied to the newly executed program.

    'fileactions' defines what actions will be performed upon the file
    descriptors of the spawned executable. If defined, it must be a
    SpawnFileAction object.

    'env', the enviroment, if provided, it must be a sequence object."""

    if not isinstance(filename, six.string_types):
        raise TypeError("filename must be a string")

    pid = ffi.new("pid_t *")

    spawn_args = []
    # This essentially does force_bytes in pkg.misc, but importing pkg.misc has
    # a circular import issue, so we implement the conversion here.
    for arg in args:
        if six.PY3 and isinstance(arg, six.string_types):
            arg = arg.encode()
        spawn_args.append(ffi.new("char []", arg))
    spawn_args.append(ffi.NULL)

    # Process env, if supplied by caller
    spawn_env = []
    if env:
        for arg in env:
            try:
                if six.PY3 and isinstance(arg, six.string_types):
                    arg = arg.encode()
                spawn_env.append(ffi.new("char []", arg))
            except:
                # If an environment variable cannot be added for any reason,
                # just continue. (Most likely is UnicodeEncodeError)
                pass
    spawn_env.append(ffi.NULL)

    # setup file actions, if passed by caller
    s_action = ffi.NULL
    if fileactions:
        if not isinstance(fileactions, SpawnFileAction):
            raise TypeError("fileact must be a SpawnFileAction object.")
        s_action = fileactions.fa

    # Now do the actual spawn
    rc = lib.posix_spawnp(pid, filename.encode(), s_action, ffi.NULL,
                          spawn_args, spawn_env)
    _check_error(rc)

    return pid[0]
Пример #2
0
 def __init__(self):
     self.fa = ffi.new("posix_spawn_file_actions_t *")
     rc = lib.posix_spawn_file_actions_init(self.fa)
     self.fa = ffi.gc(self.fa, lib.posix_spawn_file_actions_destroy)
     # The file_actions routines don't set errno, so we have to create
     # the exception tuple by hand.
     _check_error(rc)
Пример #3
0
    def add_close_childfds(self, start_fd, except_fd=-1):
        """Add to a SpawnFileAction a series of 'closes' that will close all of
        the fds >= startfd in the child process.  A single fd may be skipped,
        provided that it is given as the optional except argument."""

        if not isinstance(start_fd, int):
            raise TypeError("start_fd must be int type")
        if not isinstance(except_fd, int):
            raise TypeError("except_fd must be int type")

        # Set up walk_data for fdwalk.
        wd = ffi.new("walk_data *", [0])
        wd.skip_fd = ffi.cast("int", except_fd)
        wd.start_fd = ffi.cast("int", start_fd)
        wd.fap = self.fa

        # Perform the walk.
        lib.fdwalk(walk_func, wd)