#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
import os
import types
import six
import subprocess
try:
except ImportError:
pass
if "bufsize" not in kwargs:
if "posix_spawnp" in globals():
"""Execute program using posix spawn"""
if shell:
if executable == None:
sfa = SpawnFileAction()
# Child file actions
# Close parent's pipe ends
closed_fds = []
if p2cwrite:
if c2pread:
if errread:
# When duping fds, if there arises a situation
# where one of the fds is either 0, 1 or 2, it
# is possible that it is overwritten (#12607).
if c2pwrite == 0:
# Dup fds for child
if p2cread:
if c2pwrite:
if errwrite:
# Close pipe fds. Make sure we don't close the
# same fd more than once.
if p2cread:
if cwd != None:
if preexec_fn:
# Close all other fds, if asked for - after
# preexec_fn(), which may open FDs.
if close_fds:
#
# This is a bit tricky. Due to a sad
# behaviour with posix_spawn in nevada
# builds before the fix for 6807216 (in
# nevada 110), (and perhaps on other OS's?)
# you can't have two close actions close the
# same FD, or an error results. So we track
# everything we have closed, then manually
# fstat and close up to the max we have
# closed) . Then we close everything above
# that efficiently with add_close_childfds().
#
# scheduled closed already? skip
if i in closed_fds:
continue
try:
closed_fds.append(i)
except OSError:
pass
if env is None:
# If caller didn't pass us an environment in
# env, borrow the env that the current process
# is using.
# The bundled subprocess module takes a dict in
# the "env" argument. Allow that here by doing
# the explicit conversion to a list.
env = [
"{0}={1}".format(k, v)
]
if to_close:
else:
# Parent
else:
if shell:
if executable is None:
sfa = SpawnFileAction()
# Child file actions
# Close parent's pipe ends
closed_fds = []
if p2cwrite != -1:
if c2pread != -1:
if errread != -1:
# Dup fds for child
if p2cread != -1:
if c2pwrite != -1:
if errwrite != -1:
# Close pipe fds. Make sure we don't close the
# same fd more than once, or standard fds.
if cwd is not None:
if preexec_fn:
# Close all other fds, if asked for - after
# preexec_fn(), which may open FDs.
if close_fds:
#
# This is a bit tricky. Due to a sad
# behaviour with posix_spawn in nevada
# builds before the fix for 6807216 (in
# nevada 110), (and perhaps on other OS's?)
# you can't have two close actions close the
# same FD, or an error results. So we track
# everything we have closed, then manually
# fstat and close up to the max we have
# closed) . Then we close everything above
# that efficiently with add_close_childfds().
#
# max() can't call on empty list, use a
# trick "close_fds or [0]" to return 0
# when closed_fds is empty.
# scheduled closed already? skip
if i in closed_fds:
continue
try:
closed_fds.append(i)
except OSError:
pass
if env is None:
# If caller didn't pass us an environment in
# env, borrow the env that the current process
# is using.
# The bundled subprocess module takes a dict in
# the "env" argument. Allow that here by doing
# the explicit conversion to a list.
env = [
"{0}={1}".format(k, v)
]
env)
# parent
p2cread != devnull_fd:
c2pwrite != devnull_fd:
errwrite != devnull_fd:
if devnull_fd is not None: