|
|
# encoding: utf-8
|
|
|
|
|
|
"""
|
|
|
Stdout/stderr redirector, at the OS level, using file descriptors.
|
|
|
|
|
|
This also works under windows.
|
|
|
"""
|
|
|
|
|
|
__docformat__ = "restructuredtext en"
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
# Copyright (C) 2008 The IPython Development Team
|
|
|
#
|
|
|
# Distributed under the terms of the BSD License. The full license is in
|
|
|
# the file COPYING, distributed as part of this software.
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
import os
|
|
|
import sys
|
|
|
|
|
|
STDOUT = 1
|
|
|
STDERR = 2
|
|
|
|
|
|
class FDRedirector(object):
|
|
|
""" Class to redirect output (stdout or stderr) at the OS level using
|
|
|
file descriptors.
|
|
|
"""
|
|
|
|
|
|
def __init__(self, fd=STDOUT):
|
|
|
""" fd is the file descriptor of the outpout you want to capture.
|
|
|
It can be STDOUT or STERR.
|
|
|
"""
|
|
|
self.fd = fd
|
|
|
self.started = False
|
|
|
self.piper = None
|
|
|
self.pipew = None
|
|
|
|
|
|
def start(self):
|
|
|
""" Setup the redirection.
|
|
|
"""
|
|
|
if not self.started:
|
|
|
self.oldhandle = os.dup(self.fd)
|
|
|
self.piper, self.pipew = os.pipe()
|
|
|
os.dup2(self.pipew, self.fd)
|
|
|
os.close(self.pipew)
|
|
|
|
|
|
self.started = True
|
|
|
|
|
|
def flush(self):
|
|
|
""" Flush the captured output, similar to the flush method of any
|
|
|
stream.
|
|
|
"""
|
|
|
if self.fd == STDOUT:
|
|
|
sys.stdout.flush()
|
|
|
elif self.fd == STDERR:
|
|
|
sys.stderr.flush()
|
|
|
|
|
|
def stop(self):
|
|
|
""" Unset the redirection and return the captured output.
|
|
|
"""
|
|
|
if self.started:
|
|
|
self.flush()
|
|
|
os.dup2(self.oldhandle, self.fd)
|
|
|
os.close(self.oldhandle)
|
|
|
f = os.fdopen(self.piper, 'r')
|
|
|
output = f.read()
|
|
|
f.close()
|
|
|
|
|
|
self.started = False
|
|
|
return output
|
|
|
else:
|
|
|
return ''
|
|
|
|
|
|
def getvalue(self):
|
|
|
""" Return the output captured since the last getvalue, or the
|
|
|
start of the redirection.
|
|
|
"""
|
|
|
output = self.stop()
|
|
|
self.start()
|
|
|
return output
|
|
|
|