Skip to content

Commit 0980d74

Browse files
committed
change preexec_fn usage in Popen to start_new_session=True instead
1 parent 9c4f09b commit 0980d74

File tree

6 files changed

+40
-13
lines changed

6 files changed

+40
-13
lines changed

devlib/connection.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,21 @@ def __enter__(self):
424424
self.popen.__enter__()
425425
return self
426426

427+
def __exit__(self, *args, **kwargs):
428+
# Send SIGINT to the process group to allow it to clean up if it is running
429+
if self.popen and self.popen.poll() is None:
430+
try:
431+
os.killpg(self.popen.pid, signal.SIGINT)
432+
except Exception:
433+
pass
434+
try:
435+
# allow a graceful termination for 60 seconds
436+
self.popen.wait(timeout=60)
437+
except subprocess.TimeoutExpired:
438+
# If the process did not terminate, send SIGKILL
439+
os.killpg(self.popen.pid, signal.SIGKILL)
440+
self.popen.wait()
441+
427442

428443
class ParamikoBackgroundCommand(BackgroundCommand):
429444
"""
@@ -638,6 +653,21 @@ def __enter__(self):
638653
self.adb_popen.__enter__()
639654
return self
640655

656+
def __exit__(self, *args, **kwargs):
657+
# Send SIGINT to the process group to allow it to clean up if it is running
658+
if self.adb_popen.poll() is None:
659+
try:
660+
os.killpg(self.adb_popen.pid, signal.SIGINT)
661+
except Exception:
662+
pass
663+
try:
664+
# allow a graceful termination for 60 seconds
665+
self.adb_popen.wait(timeout=60)
666+
except subprocess.TimeoutExpired:
667+
# If the process did not terminate, send SIGKILL
668+
os.killpg(self.adb_popen.pid, signal.SIGKILL)
669+
self.adb_popen.wait()
670+
641671

642672
class TransferManager:
643673
def __init__(self, conn, transfer_poll_period=30, start_transfer_poll_delay=30, total_transfer_timeout=3600):

devlib/host.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@ def background(self, command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, as
144144

145145
# Make sure to get a new PGID so PopenBackgroundCommand() can kill
146146
# all sub processes that could be started without troubles.
147-
def preexec_fn():
148-
os.setpgrp()
149147

150148
def make_init_kwargs(command):
151149
popen = subprocess.Popen(
@@ -154,7 +152,7 @@ def make_init_kwargs(command):
154152
stderr=stderr,
155153
stdin=subprocess.PIPE,
156154
shell=True,
157-
preexec_fn=preexec_fn,
155+
start_new_session=True,
158156
)
159157
return dict(
160158
popen=popen,

devlib/instrument/arm_energy_probe.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ def reset(self, sites=None, kinds=None, channels=None):
102102

103103
def start(self):
104104
self.logger.debug(self.command)
105+
# FIXME - replace this preexec_fn arg with start_new_session argument.
106+
# to address https://github.com/ARM-software/devlib/issues/708.
107+
# didnt do it with initial change for the fix due to lack of test hardware
105108
self.armprobe = subprocess.Popen(self.command,
106109
stderr=self.output_fd_error,
107110
preexec_fn=os.setpgrp,

devlib/instrument/energy_probe.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ def reset(self, sites=None, kinds=None, channels=None):
7575

7676
def start(self):
7777
self.logger.debug(self.command)
78+
# FIXME - replace this preexec_fn arg with start_new_session argument.
79+
# to address https://github.com/ARM-software/devlib/issues/708.
80+
# didnt do it with initial change for the fix due to lack of test hardware
7881
self.process = subprocess.Popen(self.command,
7982
stdout=subprocess.PIPE,
8083
stderr=subprocess.PIPE,

devlib/utils/android.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,8 @@ def with_uuid(cmd):
687687
adb_cmd = get_adb_command(device, 'shell', adb_server, adb_port)
688688
full_command = f'{adb_cmd} {quote(command)}'
689689
logger.debug(full_command)
690-
p = subprocess.Popen(full_command, stdout=stdout, stderr=stderr, stdin=subprocess.PIPE, shell=True)
690+
p = subprocess.Popen(full_command, stdout=stdout, stderr=stderr, stdin=subprocess.PIPE, shell=True,
691+
start_new_session=True)
691692

692693
# Out of band PID lookup, to avoid conflicting needs with stdout redirection
693694
grep_cmd = f'{busybox} grep {quote(command_uuid)}'

devlib/utils/misc.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,6 @@ def get_cpu_name(implementer, part, variant):
136136
return name
137137

138138

139-
def preexec_function():
140-
# Change process group in case we have to kill the subprocess and all of
141-
# its children later.
142-
# TODO: this is Unix-specific; would be good to find an OS-agnostic way
143-
# to do this in case we wanna port WA to Windows.
144-
os.setpgrp()
145-
146-
147139
check_output_logger = logging.getLogger('check_output')
148140

149141
def get_subprocess(command, **kwargs):
@@ -153,7 +145,7 @@ def get_subprocess(command, **kwargs):
153145
stdout=subprocess.PIPE,
154146
stderr=subprocess.PIPE,
155147
stdin=subprocess.PIPE,
156-
preexec_fn=preexec_function,
148+
start_new_session=True,
157149
**kwargs)
158150

159151

0 commit comments

Comments
 (0)