mirror of
https://github.com/9001/copyparty.git
synced 2025-08-18 09:22:31 -06:00
recursive kill mtp on timeout
This commit is contained in:
parent
4792c2770d
commit
8fef9e363e
|
@ -30,6 +30,12 @@ try:
|
||||||
except:
|
except:
|
||||||
HAVE_SQLITE3 = False
|
HAVE_SQLITE3 = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
HAVE_PSUTIL = True
|
||||||
|
import psutil
|
||||||
|
except:
|
||||||
|
HAVE_PSUTIL = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import types
|
import types
|
||||||
from collections.abc import Callable, Iterable
|
from collections.abc import Callable, Iterable
|
||||||
|
@ -1489,6 +1495,78 @@ def guess_mime(url: str, fallback: str = "application/octet-stream") -> str:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def getalive(pids: list[int], pgid: int) -> list[int]:
|
||||||
|
alive = []
|
||||||
|
for pid in pids:
|
||||||
|
if pgid:
|
||||||
|
try:
|
||||||
|
# check if still one of ours
|
||||||
|
if os.getpgid(pid) == pgid:
|
||||||
|
alive.append(pid)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# windows doesn't have pgroups; assume
|
||||||
|
psutil.Process(pid)
|
||||||
|
alive.append(pid)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return alive
|
||||||
|
|
||||||
|
|
||||||
|
def killtree(root: int) -> None:
|
||||||
|
"""still racy but i tried"""
|
||||||
|
try:
|
||||||
|
# limit the damage where possible (unixes)
|
||||||
|
pgid = os.getpgid(os.getpid())
|
||||||
|
except:
|
||||||
|
pgid = 0
|
||||||
|
|
||||||
|
if HAVE_PSUTIL:
|
||||||
|
pids = [root]
|
||||||
|
parent = psutil.Process(root)
|
||||||
|
for child in parent.children(recursive=True):
|
||||||
|
pids.append(child.pid)
|
||||||
|
child.terminate()
|
||||||
|
parent.terminate()
|
||||||
|
parent = None
|
||||||
|
elif pgid:
|
||||||
|
# linux-only
|
||||||
|
pids = []
|
||||||
|
chk = [root]
|
||||||
|
while chk:
|
||||||
|
pid = chk[0]
|
||||||
|
chk = chk[1:]
|
||||||
|
pids.append(pid)
|
||||||
|
_, t, _ = runcmd(["pgrep", "-P", str(pid)])
|
||||||
|
chk += [int(x) for x in t.strip().split("\n") if x]
|
||||||
|
|
||||||
|
pids = getalive(pids, pgid) # filter to our pgroup
|
||||||
|
for pid in pids:
|
||||||
|
os.kill(pid, signal.SIGTERM)
|
||||||
|
else:
|
||||||
|
# windows gets minimal effort sorry
|
||||||
|
os.kill(pid, signal.SIGTERM)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not pids:
|
||||||
|
return # yay
|
||||||
|
|
||||||
|
for n in range(10):
|
||||||
|
time.sleep(0.1)
|
||||||
|
pids = getalive(pids, pgid)
|
||||||
|
if not pids or n > 3 and pids == [root]:
|
||||||
|
break
|
||||||
|
|
||||||
|
for pid in pids:
|
||||||
|
try:
|
||||||
|
os.kill(pid, signal.SIGKILL)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def runcmd(
|
def runcmd(
|
||||||
argv: Union[list[bytes], list[str]], timeout: Optional[int] = None, **ka: Any
|
argv: Union[list[bytes], list[str]], timeout: Optional[int] = None, **ka: Any
|
||||||
) -> tuple[int, str, str]:
|
) -> tuple[int, str, str]:
|
||||||
|
@ -1499,7 +1577,7 @@ def runcmd(
|
||||||
try:
|
try:
|
||||||
stdout, stderr = p.communicate(timeout=timeout)
|
stdout, stderr = p.communicate(timeout=timeout)
|
||||||
except sp.TimeoutExpired:
|
except sp.TimeoutExpired:
|
||||||
p.kill()
|
killtree(p.pid)
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
|
|
||||||
stdout = stdout.decode("utf-8", "replace")
|
stdout = stdout.decode("utf-8", "replace")
|
||||||
|
|
Loading…
Reference in a new issue