Skip to content

Commit e690318

Browse files
darwin::internal_platform_utils is rewritten
_FindPostmaster - uses "-ewwo" (as in linux version) ProcessIsZombi_soft_check - new exact code, "-wwo" is used
1 parent 07c307d commit e690318

1 file changed

Lines changed: 59 additions & 34 deletions

File tree

‎src/impl/platforms/darwin/internal_platform_utils.py‎

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import shlex
1414
import typing
1515
import time
16+
import subprocess
1617

1718

1819
class InternalPlatformUtils(base.InternalPlatformUtils):
@@ -107,15 +108,12 @@ def _FindPostmaster(
107108
assert type(pg_path_e) is str
108109
assert type(data_dir_e) is str
109110

110-
# The regular expression remains the same since the output structure pid, ppid, args is the same
111111
regexp = r"^\s*[0-9]+\s+[0-9]+\s+" + pg_path_e + r"(\s+.*)?\s+\-[D]\s+" + data_dir_e + r"(\s+.*)?"
112112

113-
# Change for macOS: Instead of Linux flag-combo "-ewwo"
114-
# we use the standard POSIX "-eo", which works on macOS without trimming argument strings
115113
cmd = [
116114
__class__.C_BASH_EXE,
117115
"-c",
118-
"ps -eo \"pid=,ppid=,args=\" | grep -E " + shlex.quote(regexp),
116+
"ps -ewwo \"pid=,ppid=,args=\" | grep -E " + shlex.quote(regexp),
119117
]
120118

121119
exec_r = os_ops.run(
@@ -260,46 +258,73 @@ def ProcessIsZombi_soft_check(
260258

261259
# Change for macOS: Instead of reading non-existent /proc/PID/stat,
262260
# we make a native call to the system ps and request the status (state) of the process.
263-
cmd = ["ps", "-p", str(pid), "-o", "state="]
261+
cmd = ["ps", "-p", str(pid), "-wwo", "state="]
264262

265-
try:
266-
exec_r = os_ops.run(
267-
cmd=cmd,
268-
check=False,
269-
exec_env=__class__.sm_exec_env,
270-
)
271-
272-
assert type(exec_r) is OsCommandResult
273-
274-
# Если процесс не найден (уже завершился и стерт), ps вернет код 1
275-
if exec_r.returncode != 0:
276-
return False
263+
exec_r = os_ops.run(
264+
cmd=cmd,
265+
check=False,
266+
exec_env=__class__.sm_exec_env,
267+
stdout=subprocess.PIPE,
268+
)
277269

278-
proc_status = exec_r.stdout.decode("utf-8", errors="ignore").strip()
270+
assert type(exec_r) is OsCommandResult
271+
assert type(exec_r.stdout) is bytes
279272

280-
if not proc_status:
281-
return False
273+
# If the process is not found (already terminated and deleted), ps will return code 1
274+
if exec_r.returncode == 1:
275+
return False
282276

283-
# В BSD-системах статус зомби обозначается буквой 'Z'
284-
return proc_status.startswith("Z")
277+
if exec_r.returncode != 0:
278+
return None
285279

286-
except Exception as e:
287-
# If the file disappeared right during reading, it means the process is completely erased
288-
if __class__._is_file_not_found_exception(e):
289-
return False
280+
proc_status = exec_r.stdout.decode("utf-8").rstrip()
290281

291-
return None
282+
if not proc_status:
283+
return None
292284

293-
@staticmethod
294-
def _is_file_not_found_exception(e: Exception) -> bool:
295-
if isinstance(e, FileNotFoundError):
285+
assert len(proc_status) > 0
286+
287+
# state The state is given by a sequence of letters, for example,
288+
# "RWNA". The first letter indicates the run state of the process:
289+
#
290+
# D Marks a process in disk (or other short term, uninterruptible) wait.[legacy option]
291+
# I Marks a process that is idle (sleeping for longer than about 20 seconds).
292+
# R Marks a runnable process.
293+
# S Marks a process that is sleeping for less than about 20 seconds.
294+
# T Marks a stopped process.
295+
# U Marks a process in uninterruptible wait.
296+
# Z Marks a dead process (a 'zombie').
297+
#
298+
# Additional characters after these, if any, indicate additional
299+
# state information:
300+
#
301+
# + The process is in the foreground process group of its control terminal.
302+
# < The process has raised CPU scheduling priority.
303+
# > The process has specified a soft limit on memory requirements and is currently
304+
# exceeding that limit; such a process is (necessarily) not swapped.
305+
# A the process has asked for random page replacement
306+
# (VA_ANOM, from vadvise(2), for example, lisp(1) in a garbage collect).
307+
# E The process is trying to exit.
308+
# L The process has pages locked in core (for example, for raw I/O).
309+
# N The process has reduced CPU scheduling priority (see setpriority(2)).
310+
# S The process has asked for FIFO page replacement (VA_SEQL,
311+
# from vadvise(2), for example, a large image processing
312+
# program using virtual memory to sequentially address
313+
# voluminous data).
314+
# s The process is a session leader.
315+
# V The process is suspended during a vfork.
316+
# W The process is swapped out.
317+
# X The process is being traced or debugged.
318+
319+
ch1 = proc_status[0]
320+
321+
if ch1 == "Z":
296322
return True
297323

298-
if isinstance(e, ExecUtilException):
299-
if e.exit_code == 2:
300-
return True
324+
if ch1 in "DIRSTU":
325+
return False
301326

302-
return False
327+
return None
303328

304329
T_PID_TO_PPID = typing.Dict[int, int]
305330

0 commit comments

Comments
 (0)