Skip to content

Commit 37d5600

Browse files
author
Andy C
committed
[refactor] WaitForOne() returns signal number rather than exit code.
This should make it simpler to test for SIGWINCH.
1 parent a264f12 commit 37d5600

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

core/process.py

+8-11
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ def JobWait(self, waiter):
918918
while self.state == job_state_e.Running:
919919
result = waiter.WaitForOne()
920920

921-
if result > 0: # signal
921+
if result >= 0: # signal
922922
return wait_status.Cancelled(result)
923923

924924
if result == W1_ECHILD:
@@ -1079,7 +1079,7 @@ def JobWait(self, waiter):
10791079
while self.state == job_state_e.Running:
10801080
result = waiter.WaitForOne()
10811081

1082-
if result > 0: # signal
1082+
if result >= 0: # signal
10831083
return wait_status.Cancelled(result)
10841084

10851085
if result == W1_ECHILD:
@@ -1402,11 +1402,11 @@ def WaitForOne(self):
14021402
will try again.
14031403
14041404
Callers:
1405-
wait -n -- WaitForOne() just once
1406-
wait -- WaitForOne() in a loop
1407-
wait $! -- job.JobWait()
1408-
Process::Wait()
1409-
Pipeline::Wait()
1405+
wait -n -- loop until there is one fewer process (TODO)
1406+
wait -- loop until there are no processes
1407+
wait $! -- loop until job state is Done (process or pipeline)
1408+
Process::Wait() -- loop until Process state is done
1409+
Pipeline::Wait() -- loop until Pipeline state is done
14101410
14111411
Comparisons:
14121412
bash: jobs.c waitchld() Has a special case macro(!) CHECK_WAIT_INTR for
@@ -1435,10 +1435,7 @@ def WaitForOne(self):
14351435
if e.errno == ECHILD:
14361436
return W1_ECHILD # nothing to wait for caller should stop
14371437
elif e.errno == EINTR: # Bug #858 fix
1438-
# Examples:
1439-
# - 128 + SIGUSR1 = 128 + 10 = 138
1440-
# - 128 + SIGUSR2 = 128 + 12 = 140
1441-
return 128 + self.sig_state.last_sig_num
1438+
return self.sig_state.last_sig_num # e.g. 1 for SIGHUP
14421439
else:
14431440
# The signature of waitpid() means this shouldn't happen
14441441
raise AssertionError()

core/runtime.asdl

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ module runtime
155155
Proc(int code)
156156
| Pipeline(int* codes)
157157
-- because the 'wait' builtin is interruptible
158-
| Cancelled(int code)
158+
| Cancelled(int sig_num)
159159

160160
-- For word splitting (in frontend/consts.py and osh/split.py)
161161
span = Black | Delim | Backslash

osh/builtin_process.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,16 @@ def _Run(self, cmd_val):
147147
# But note that it can be interrupted by a signal and will return say
148148
# status=156 for SIGWINCH
149149

150+
# TODO: WaitForOne() in a loop and ignore SIGWINCH here. We run until we
151+
# reach a STATE.
152+
150153
result = self.waiter.WaitForOne()
151154
if result == process.W1_OK:
152155
return self.waiter.last_status
153156
elif result == process.W1_ECHILD: # nothing to wait for
154157
return 127
155158
else:
156-
return result # signal, e.g. SIGHUP is 129 = 128 + 1
159+
return 128 + result # signal, e.g. SIGHUP is 129 = 128 + 1
157160

158161
if len(job_ids) == 0:
159162
#log('*** wait')
@@ -167,8 +170,8 @@ def _Run(self, cmd_val):
167170
result = self.waiter.WaitForOne()
168171
if result == process.W1_ECHILD: # nothing to wait for, or interrupted. status is 0
169172
break
170-
elif result > 0: # signal
171-
status = result
173+
elif result >= 0: # signal
174+
status = 128 + result
172175
break
173176

174177
i += 1
@@ -217,7 +220,7 @@ def _Run(self, cmd_val):
217220
status = wait_status.codes[-1]
218221
elif case(wait_status_e.Cancelled):
219222
wait_status = cast(wait_status__Cancelled, UP_wait_status)
220-
status = wait_status.code
223+
status = 128 + wait_status.sig_num
221224
else:
222225
raise AssertionError()
223226

0 commit comments

Comments
 (0)