summaryrefslogtreecommitdiffstats
path: root/scripts/redirect.py
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2010-11-01 01:35:04 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2010-11-01 01:35:04 -0700
commit6130e39b18b5f53902e4eab14f6d5cdde5219563 (patch)
tree0db0628479a1b750e9af1f66cb8379ebd0913d31 /scripts/redirect.py
parentf0e77f6797c0504b0da25a56152b707d3357f386 (diff)
downloadabc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.gz
abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.tar.bz2
abc-6130e39b18b5f53902e4eab14f6d5cdde5219563.zip
initial commit of public abc
Diffstat (limited to 'scripts/redirect.py')
-rw-r--r--scripts/redirect.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/scripts/redirect.py b/scripts/redirect.py
new file mode 100644
index 00000000..498fe150
--- /dev/null
+++ b/scripts/redirect.py
@@ -0,0 +1,94 @@
+"""
+
+A simple context manager for redirecting streams in Python.
+The streams are redirected at the the C runtime level so that the output of C extensions
+that use stdio will also be redirected.
+
+null_file : a stream representing the null device (e.g. /dev/null on Unix)
+redirect: a context manager for redirecting streams
+
+Author: Baruch Sterin (sterin@berkeley.edu)
+
+"""
+
+import os
+import sys
+
+from contextlib import contextmanager
+
+null_file = open( os.devnull, "w" )
+
+@contextmanager
+def _dup( f ):
+ fd = os.dup( f.fileno() )
+ yield fd
+ os.close(fd)
+
+@contextmanager
+def redirect(dst = null_file, src = sys.stdout):
+
+ """
+ Redirect the src stream into dst.
+
+ Example:
+ with redirect( open("somefile.txt", sys.stdout ) ):
+ do some stuff ...
+ """
+
+ if src.fileno() == dst.fileno():
+ yield
+ return
+
+ with _dup( src ) as fd_dup_src:
+
+ dst.flush()
+
+ src.flush()
+ os.close( src.fileno() )
+ os.dup2( dst.fileno(), src.fileno() )
+
+ yield
+
+ src.flush()
+ os.close( src.fileno() )
+ os.dup2( fd_dup_src, src.fileno() )
+
+def start_redirect(dst = null_file, src = sys.stdout):
+
+ """
+ Start redirection of src stream into dst. Return the duplicated file handle of the source.
+
+ Example:
+ fd = start_redirect( open("somefile.txt"), sys.stdout )
+ ... do some stuff ...
+ end_redirect(sys.stdout, fd)
+ """
+
+ if src.fileno() == dst.fileno():
+ return None
+
+ fd_dup_src = os.dup( src.fileno() )
+
+ dst.flush()
+ src.flush()
+
+ os.close( src.fileno() )
+ os.dup2( dst.fileno(), src.fileno() )
+
+ return fd_dup_src
+
+def end_redirect(src, fd_dup_src):
+
+ """
+ End redirection of stream src.Redirect the src stream into dst. src is the source stream and fd_dup_src is the value returned by
+ start_redirect()
+ """
+
+ if fd_dup_src is None:
+ return
+
+ src.flush()
+ os.close( src.fileno() )
+ os.dup2( fd_dup_src, src.fileno() )
+
+ os.close(fd_dup_src)