powerprofilesctl: Use posix-compliant exit codes on signals

Do not return the python exit code when the launched process exit
because of a signal, but instead expose it as it is.
This commit is contained in:
Marco Trevisan (Treviño) 2024-04-01 15:30:30 +02:00 committed by Mario Limonciello
parent 15c74efc7e
commit 0c80ae1108
2 changed files with 35 additions and 9 deletions

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python3
import argparse
import os
import signal
import subprocess
import sys
@ -124,21 +125,29 @@ def _launch(args):
)
cookie = proxy.HoldProfile("(sss)", profile, reason, appid)
# Kill child when we go away
def receive_signal(_signum, _stack):
launched_app.terminate()
signal.signal(signal.SIGTERM, receive_signal)
# print (f'Got {cookie} for {profile} hold')
with subprocess.Popen(args.arguments) as launched_app:
# Redirect the same signal to the child
def receive_signal(signum, _stack):
launched_app.send_signal(signum)
signal.signal(signal.SIGTERM, receive_signal)
try:
launched_app.wait()
ret = launched_app.returncode
except KeyboardInterrupt:
ret = launched_app.returncode
signal.signal(signal.SIGTERM, signal.SIG_DFL)
proxy.ReleaseProfile("(u)", cookie)
if ret < 0:
# Use standard POSIX signal exit code.
os.kill(os.getpid(), -ret)
return
sys.exit(ret)

View file

@ -21,6 +21,7 @@
import os
import subprocess
import signal
import sys
import tempfile
import time
@ -1625,9 +1626,9 @@ class Tests(dbusmock.DBusTestCase):
released_cookie = None
def signal_cb(_, sender, signal, params):
def signal_cb(_, sender, signal_name, params):
nonlocal released_cookie
if signal == "ProfileReleased":
if signal_name == "ProfileReleased":
released_cookie = params
self.addCleanup(
@ -1772,6 +1773,22 @@ class Tests(dbusmock.DBusTestCase):
cmd = subprocess.run(tool_cmd + ["launch", "sh", "-c", "exit 55"], check=False)
self.assertEqual(cmd.returncode, 55)
def test_launch_with_command_signaled(self):
self.create_platform_profile()
self.start_daemon()
self.assert_eventually(lambda: self.get_dbus_property("ActiveProfile"))
tool_cmd = self.powerprofilesctl_command()
cmd = subprocess.run(
tool_cmd + ["launch", "sh", "-c", f"kill -{signal.SIGKILL} $$"], check=False
)
self.assertEqual(cmd.returncode, -signal.SIGKILL)
cmd = subprocess.run(
tool_cmd + ["launch", "sh", "-c", f"kill -{signal.SIGINT} $$"], check=False
)
self.assertEqual(cmd.returncode, -signal.SIGINT)
def test_vanishing_hold(self):
self.create_platform_profile()
self.start_daemon()
@ -1793,7 +1810,7 @@ class Tests(dbusmock.DBusTestCase):
# Make sure to handle vanishing clients
launch_process.terminate()
retcode = launch_process.wait()
self.assertTrue(os.WIFSIGNALED(retcode))
self.assertEqual(retcode, -signal.SIGTERM)
holds = self.get_dbus_property("ActiveProfileHolds")
self.assertEqual(len(holds), 0)