mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
posix: implement readpipe using non-blocking I/O (issue4336)
On Linux, fstat().st_size of a pipe always returns 0, even if the pipe has data available for reading. This meant that reading from and subsequently printing the stderr pipe content after wireproto commands over SSH meant that available data wasn't being printed. We now implement pipe reading on POSIX by doing a non-blocking read for all available data.
This commit is contained in:
parent
db57d5e9d6
commit
6799e4f38a
@ -8,6 +8,7 @@
|
||||
from i18n import _
|
||||
import encoding
|
||||
import os, sys, errno, stat, getpass, pwd, grp, socket, tempfile, unicodedata
|
||||
import fcntl
|
||||
|
||||
posixfile = open
|
||||
normpath = os.path.normpath
|
||||
@ -432,7 +433,7 @@ def gethgcmd():
|
||||
|
||||
def termwidth():
|
||||
try:
|
||||
import termios, array, fcntl
|
||||
import termios, array
|
||||
for dev in (sys.stderr, sys.stdout, sys.stdin):
|
||||
try:
|
||||
try:
|
||||
@ -570,13 +571,24 @@ def statisexec(st):
|
||||
|
||||
def readpipe(pipe):
|
||||
"""Read all available data from a pipe."""
|
||||
# We can't fstat() a pipe because Linux will always report 0.
|
||||
# So, we set the pipe to non-blocking mode and read everything
|
||||
# that's available.
|
||||
flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
|
||||
flags |= os.O_NONBLOCK
|
||||
oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
|
||||
|
||||
try:
|
||||
chunks = []
|
||||
while True:
|
||||
size = os.fstat(pipe.fileno()).st_size
|
||||
if not size:
|
||||
break
|
||||
|
||||
s = pipe.read(size)
|
||||
try:
|
||||
s = pipe.read()
|
||||
if not s:
|
||||
break
|
||||
chunks.append(s)
|
||||
except IOError:
|
||||
break
|
||||
|
||||
return ''.join(chunks)
|
||||
finally:
|
||||
fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
|
||||
|
Loading…
Reference in New Issue
Block a user