Among our users at Google, we're still seeing several percent of
commands fail with exit code 255. I suspect keyboard interrupts is an
important remaining reason.
This is a resend of D10086 with some fixes for pager handling added
ahead of it.
( )
| pulkit |
| hg-reviewers |
Among our users at Google, we're still seeing several percent of
commands fail with exit code 255. I suspect keyboard interrupts is an
important remaining reason.
This is a resend of D10086 with some fixes for pager handling added
ahead of it.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/dispatch.py (5 lines) | |||
| M | tests/test-chg.t (4 lines) | |||
| M | tests/test-commandserver.t (2 lines) | |||
| M | tests/test-nointerrupt.t (6 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | martinvonz | ||
| Closed | martinvonz | ||
| Closed | martinvonz |
| req.ui.error(msg) | req.ui.error(msg) | ||||
| except error.SignalInterrupt: | except error.SignalInterrupt: | ||||
| # maybe pager would quit without consuming all the output, and | # maybe pager would quit without consuming all the output, and | ||||
| # SIGPIPE was raised. we cannot print anything in this case. | # SIGPIPE was raised. we cannot print anything in this case. | ||||
| pass | pass | ||||
| except IOError as inst: | except IOError as inst: | ||||
| if inst.errno != errno.EPIPE: | if inst.errno != errno.EPIPE: | ||||
| raise | raise | ||||
| if req.ui.configbool(b'ui', b'detailed-exit-code'): | |||||
| ret = 250 | |||||
| else: | |||||
| ret = -1 | ret = -1 | ||||
| finally: | finally: | ||||
| duration = util.timer() - starttime | duration = util.timer() - starttime | ||||
| try: | try: | ||||
| req.ui.flush() # record blocked times | req.ui.flush() # record blocked times | ||||
| except BaseException: | except BaseException: | ||||
| pass | pass | ||||
| if req.ui.logblockedtimes: | if req.ui.logblockedtimes: | ||||
| req.ui._blockedtimes[b'command_duration'] = duration * 1000 | req.ui._blockedtimes[b'command_duration'] = duration * 1000 | ||||
| $ cat >> .hg/hgrc <<EOF | $ cat >> .hg/hgrc <<EOF | ||||
| > [extensions] | > [extensions] | ||||
| > bulkwrite = $TESTTMP/bulkwrite.py | > bulkwrite = $TESTTMP/bulkwrite.py | ||||
| > EOF | > EOF | ||||
| $ chg bulkwrite --pager=on --color no --config ui.formatted=True | $ chg bulkwrite --pager=on --color no --config ui.formatted=True | ||||
| paged! 'going to write massive data\n' | paged! 'going to write massive data\n' | ||||
| killed! (?) | killed! (?) | ||||
| [255] | [250] | ||||
| $ chg bulkwrite --pager=on --color no --config ui.formatted=True | $ chg bulkwrite --pager=on --color no --config ui.formatted=True | ||||
| paged! 'going to write massive data\n' | paged! 'going to write massive data\n' | ||||
| killed! (?) | killed! (?) | ||||
| [255] | [250] | ||||
| $ cd .. | $ cd .. | ||||
| missing stdio | missing stdio | ||||
| ------------- | ------------- | ||||
| $ CHGDEBUG=1 chg version -q 0<&- | $ CHGDEBUG=1 chg version -q 0<&- | ||||
| chg: debug: * stdio fds are missing (glob) | chg: debug: * stdio fds are missing (glob) | ||||
| ... runcommand(server, [b'debugsuicide']) # command can be interrupted | ... runcommand(server, [b'debugsuicide']) # command can be interrupted | ||||
| ... server.send_signal(signal.SIGTERM) # server will be terminated | ... server.send_signal(signal.SIGTERM) # server will be terminated | ||||
| ... time.sleep(1) | ... time.sleep(1) | ||||
| *** runcommand debugsleep | *** runcommand debugsleep | ||||
| *** runcommand debugsleep | *** runcommand debugsleep | ||||
| *** runcommand debugsuicide | *** runcommand debugsuicide | ||||
| interrupted! | interrupted! | ||||
| killed! | killed! | ||||
| [255] | [250] | ||||
| #endif | #endif | ||||
| structured message channel: | structured message channel: | ||||
| $ cat <<'EOF' >> repo2/.hg/hgrc | $ cat <<'EOF' >> repo2/.hg/hgrc | ||||
| > [ui] | > [ui] | ||||
| > EOF | > EOF | ||||
| Test ctrl-c | Test ctrl-c | ||||
| $ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
| $ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
| $ hg wait-signal | $ hg wait-signal | ||||
| interrupted! | interrupted! | ||||
| [255] | [250] | ||||
| $ cat >> $HGRCPATH << EOF | $ cat >> $HGRCPATH << EOF | ||||
| > [experimental] | > [experimental] | ||||
| > nointerrupt = yes | > nointerrupt = yes | ||||
| > EOF | > EOF | ||||
| $ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
| $ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
| $ hg wait-signal | $ hg wait-signal | ||||
| interrupted! | interrupted! | ||||
| [255] | [250] | ||||
| $ cat >> $HGRCPATH << EOF | $ cat >> $HGRCPATH << EOF | ||||
| > [experimental] | > [experimental] | ||||
| > nointerrupt-interactiveonly = False | > nointerrupt-interactiveonly = False | ||||
| > EOF | > EOF | ||||
| $ rm -f $SYNC_FILE $DONE_FILE | $ rm -f $SYNC_FILE $DONE_FILE | ||||
| $ sh -c "../send-signal.sh INT" & | $ sh -c "../send-signal.sh INT" & | ||||
| $ hg wait-signal | $ hg wait-signal | ||||
| shutting down cleanly | shutting down cleanly | ||||
| press ^C again to terminate immediately (dangerous) | press ^C again to terminate immediately (dangerous) | ||||
| end of unsafe operation | end of unsafe operation | ||||
| interrupted! | interrupted! | ||||
| [255] | [250] | ||||