##// END OF EJS Templates
chgserver: discard buffered output before restoring fds (issue6207)...
Yuya Nishihara -
r45745:a17454a1 stable
parent child Browse files
Show More
@@ -434,8 +434,11 b' class chgcmdserver(commandserver.server)'
434 self._oldios.append((ch, fp, fd))
434 self._oldios.append((ch, fp, fd))
435
435
436 def _restoreio(self):
436 def _restoreio(self):
437 if not self._oldios:
438 return
439 nullfd = os.open(os.devnull, os.O_WRONLY)
437 ui = self.ui
440 ui = self.ui
438 for (ch, fp, fd), (cn, fn, _mode) in zip(self._oldios, _iochannels):
441 for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
439 newfp = getattr(ui, fn)
442 newfp = getattr(ui, fn)
440 # close newfp while it's associated with client; otherwise it
443 # close newfp while it's associated with client; otherwise it
441 # would be closed when newfp is deleted
444 # would be closed when newfp is deleted
@@ -443,6 +446,12 b' class chgcmdserver(commandserver.server)'
443 newfp.close()
446 newfp.close()
444 # restore original fd: fp is open again
447 # restore original fd: fp is open again
445 try:
448 try:
449 if newfp is fp and 'w' in mode:
450 # Discard buffered data which couldn't be flushed because
451 # of EPIPE. The data should belong to the current session
452 # and should never persist.
453 os.dup2(nullfd, fp.fileno())
454 fp.flush()
446 os.dup2(fd, fp.fileno())
455 os.dup2(fd, fp.fileno())
447 except OSError as err:
456 except OSError as err:
448 # According to issue6330, running chg on heavy loaded systems
457 # According to issue6330, running chg on heavy loaded systems
@@ -459,6 +468,7 b' class chgcmdserver(commandserver.server)'
459 os.close(fd)
468 os.close(fd)
460 setattr(self, cn, ch)
469 setattr(self, cn, ch)
461 setattr(ui, fn, fp)
470 setattr(ui, fn, fp)
471 os.close(nullfd)
462 del self._oldios[:]
472 del self._oldios[:]
463
473
464 def validate(self):
474 def validate(self):
@@ -152,6 +152,49 b' chg waits for pager if runcommand raises'
152 crash-pager: going to crash
152 crash-pager: going to crash
153 [255]
153 [255]
154
154
155 no stdout data should be printed after pager quits, and the buffered data
156 should never persist (issue6207)
157
158 "killed!" may be printed if terminated by SIGPIPE, which isn't important
159 in this test.
160
161 $ cat > $TESTTMP/bulkwrite.py <<'EOF'
162 > import time
163 > from mercurial import error, registrar
164 > cmdtable = {}
165 > command = registrar.command(cmdtable)
166 > @command(b'bulkwrite')
167 > def bulkwrite(ui, repo, *pats, **opts):
168 > ui.write(b'going to write massive data\n')
169 > ui.flush()
170 > t = time.time()
171 > while time.time() - t < 2:
172 > ui.write(b'x' * 1023 + b'\n') # will be interrupted by SIGPIPE
173 > raise error.Abort(b"write() doesn't block")
174 > EOF
175
176 $ cat > $TESTTMP/fakepager.py <<'EOF'
177 > import sys
178 > import time
179 > sys.stdout.write('paged! %r\n' % sys.stdin.readline())
180 > time.sleep(1) # new data will be written
181 > EOF
182
183 $ cat >> .hg/hgrc <<EOF
184 > [extensions]
185 > bulkwrite = $TESTTMP/bulkwrite.py
186 > EOF
187
188 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
189 paged! 'going to write massive data\n'
190 killed! (?)
191 [255]
192
193 $ chg bulkwrite --pager=on --color no --config ui.formatted=True
194 paged! 'going to write massive data\n'
195 killed! (?)
196 [255]
197
155 $ cd ..
198 $ cd ..
156
199
157 server lifecycle
200 server lifecycle
General Comments 0
You need to be logged in to leave comments. Login now