title: How do I prevent a C shared library to print on stdout in python?
body: <p>I work with a python lib that imports a C shared library that prints on stdout. I want a clean output in order to use it with pipes or to redirect in files. The prints are done outside of python, in the shared library.</p>
  
  <p>At the beginning, my approach was:</p>
  
  <pre><code># file: test.py
  import os
  from ctypes import *
  from tempfile import mktemp
  
  libc = CDLL("libc.so.6")
  
  print # That's here on purpose, otherwise hello word is always printed
  
  tempfile = open(mktemp(),'w')
  savestdout = os.dup(1)
  os.close(1)
  if os.dup(tempfile.fileno()) != 1:
      assert False, "couldn't redirect stdout - dup() error"
  
  # let's pretend this is a call to my library
  libc.printf("hello world\n")
  
  os.close(1)
  os.dup(savestdout)
  os.close(savestdout)
  </code></pre>
  
  <p>This first approach is half working:<br>
  - For some reason, it needs a "print" statement just before moving stdout, otherwise hello word is always printed. As a result it will print an empty line instead of all the fuzz the library usually outputs.<br>
  - More annoying, it fails when redirecting to a file:  </p>
  
  <pre><code>$python test.py &gt; foo &amp;&amp; cat foo
  
  hello world
  </code></pre>
  
  <p>My second python attempt was inspired from another similar thread given in the comments:</p>
  
  <pre><code>import os
  import sys
  from ctypes import *
  libc = CDLL("libc.so.6")
  
  devnull = open('/dev/null', 'w')
  oldstdout = os.dup(sys.stdout.fileno())
  os.dup2(devnull.fileno(), 1)
  
  # We still pretend this is a call to my library
  libc.printf("hello\n")
  
  os.dup2(oldstdout, 1)
  </code></pre>
  
  <p>This one also fails to prevent "hello" from printing.</p>
  
  <p>Since I felt this was a bit low level, I then decided to go completely with ctypes. I took inspiration from this C program, which does not print anything:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  int main(int argc, const char *argv[]) {
      char buf[20];
      int saved_stdout = dup(1);
      freopen("/dev/null", "w", stdout);
  
      printf("hello\n"); // not printed
  
      sprintf(buf, "/dev/fd/%d", saved_stdout);
      freopen(buf, "w", stdout);
  
      return 0;
  }
  </code></pre>
  
  <p>I built the following example:</p>
  
  <pre><code>from ctypes import *
  libc = CDLL("libc.so.6")
  
  saved_stdout = libc.dup(1)
  stdout = libc.fdopen(1, "w")
  libc.freopen("/dev/null", "w", stdout);
  
  libc.printf("hello\n")
  
  libc.freopen("/dev/fd/" + str(saved_stdout), "w", stdout)
  </code></pre>
  
  <p>This prints "hello", even if I libc.fflush(stdout) just after the printf. I am starting to think it may be not possible to do what I want in python. Or maybe the way I get a file pointer to stdout is not right.</p>
  
  <p>What do you think?</p>