comparison mercurial/utils/procutil.py @ 46174:a1601ff3877c

procutil: introduce pseudo file object that just raises EBADF This should be safer than closing underlying fd as the fd may be reused. On Python 2, closed sys.stdin could be redirected to a random file having fd=0, but we'd be better not copying this behavior. Only readinto() and write() are implemented according to the following ABC table. fileno() is not implemented since fd=0/1/2 may be assigned later to other files. https://docs.python.org/3/library/io.html#class-hierarchy
author Yuya Nishihara <yuya@tcha.org>
date Sat, 19 Dec 2020 11:10:18 +0900
parents 7ce24d3761e8
children a04c03b0678e
comparison
equal deleted inserted replaced
46173:a9765e0a461d 46174:a1601ff3877c
46 def isatty(fp): 46 def isatty(fp):
47 try: 47 try:
48 return fp.isatty() 48 return fp.isatty()
49 except AttributeError: 49 except AttributeError:
50 return False 50 return False
51
52
53 class BadFile(io.RawIOBase):
54 """Dummy file object to simulate closed stdio behavior"""
55
56 def readinto(self, b):
57 raise IOError(errno.EBADF, 'Bad file descriptor')
58
59 def write(self, b):
60 raise IOError(errno.EBADF, 'Bad file descriptor')
51 61
52 62
53 class LineBufferedWrapper(object): 63 class LineBufferedWrapper(object):
54 def __init__(self, orig): 64 def __init__(self, orig):
55 self.orig = orig 65 self.orig = orig
127 137
128 # sys.stdin can be None 138 # sys.stdin can be None
129 if sys.stdin: 139 if sys.stdin:
130 stdin = sys.stdin.buffer 140 stdin = sys.stdin.buffer
131 else: 141 else:
132 stdin = open(os.devnull, 'rb') 142 stdin = BadFile()
133 os.close(stdin.fileno())
134 stdout = _make_write_all(sys.stdout.buffer) 143 stdout = _make_write_all(sys.stdout.buffer)
135 stderr = _make_write_all(sys.stderr.buffer) 144 stderr = _make_write_all(sys.stderr.buffer)
136 if pycompat.iswindows: 145 if pycompat.iswindows:
137 # Work around Windows bugs. 146 # Work around Windows bugs.
138 stdout = platform.winstdout(stdout) 147 stdout = platform.winstdout(stdout)