comparison mercurial/utils/procutil.py @ 37222:7f78de1c93aa

procutil: redirect ui.fout to stderr while stdio is protected The new behavior seems slightly nicer as we can at least read the output. And this is similar to what the sshserver is doing, so we can probably reuse protectstdio() instead of the weird hook.redirect(True) hack.
author Yuya Nishihara <yuya@tcha.org>
date Sun, 25 Mar 2018 12:15:33 +0900
parents ac71cbad5da3
children 90c5ca718781
comparison
equal deleted inserted replaced
37221:ac71cbad5da3 37222:7f78de1c93aa
211 211
212 def isstdout(f): 212 def isstdout(f):
213 return _testfileno(f, sys.__stdout__) 213 return _testfileno(f, sys.__stdout__)
214 214
215 def protectstdio(uin, uout): 215 def protectstdio(uin, uout):
216 """Duplicate streams and redirect original to null if (uin, uout) are 216 """Duplicate streams and redirect original if (uin, uout) are stdio
217 stdio 217
218 If uin is stdin, it's redirected to /dev/null. If uout is stdout, it's
219 redirected to stderr so the output is still readable.
218 220
219 Returns (fin, fout) which point to the original (uin, uout) fds, but 221 Returns (fin, fout) which point to the original (uin, uout) fds, but
220 may be copy of (uin, uout). The returned streams can be considered 222 may be copy of (uin, uout). The returned streams can be considered
221 "owned" in that print(), exec(), etc. never reach to them. 223 "owned" in that print(), exec(), etc. never reach to them.
222 """ 224 """
223 uout.flush() 225 uout.flush()
224 nullfd = os.open(os.devnull, os.O_RDWR)
225 fin, fout = uin, uout 226 fin, fout = uin, uout
226 if uin is stdin: 227 if uin is stdin:
227 newfd = os.dup(uin.fileno()) 228 newfd = os.dup(uin.fileno())
229 nullfd = os.open(os.devnull, os.O_RDONLY)
228 os.dup2(nullfd, uin.fileno()) 230 os.dup2(nullfd, uin.fileno())
231 os.close(nullfd)
229 fin = os.fdopen(newfd, r'rb') 232 fin = os.fdopen(newfd, r'rb')
230 if uout is stdout: 233 if uout is stdout:
231 newfd = os.dup(uout.fileno()) 234 newfd = os.dup(uout.fileno())
232 os.dup2(nullfd, uout.fileno()) 235 os.dup2(stderr.fileno(), uout.fileno())
233 fout = os.fdopen(newfd, r'wb') 236 fout = os.fdopen(newfd, r'wb')
234 os.close(nullfd)
235 return fin, fout 237 return fin, fout
236 238
237 def restorestdio(uin, uout, fin, fout): 239 def restorestdio(uin, uout, fin, fout):
238 """Restore (uin, uout) streams from possibly duplicated (fin, fout)""" 240 """Restore (uin, uout) streams from possibly duplicated (fin, fout)"""
239 uout.flush() 241 uout.flush()