--- /dev/null
+# http://www.opengroup.org/onlinepubs/009695399/basedefs/unistd.h.html
+
+cdef extern from "unistd.h" nogil:
+
+ #:NULL
+
+ enum: R_OK
+ enum: W_OK
+ enum: X_OK
+ enum: F_OK
+
+ # confstr()
+ #_CS_PATH
+ #_CS_POSIX_*
+
+ enum: SEEK_SET
+ enum: SEEK_CUR
+ enum: SEEK_END
+
+ enum: F_LOCK
+ enum: F_TEST
+ enum: F_TLOCK
+ enum: F_ULOCK
+
+ # pathconf()
+ # _PC_*
+
+ # sysconf()
+ # _SC_*
+
+ enum: STDIN_FILENO #0
+ enum: STDOUT_FILENO #1
+ enum: STDERR_FILENO #2
+
+ #:ctypedef unsigned size_t
+ #:ctypedef signed ssize_t
+ ctypedef int uid_t
+ ctypedef int gid_t
+ ctypedef signed off_t
+ ctypedef signed pid_t
+ ctypedef unsigned useconds_t
+ ctypedef signed intptr_t
+
+ int access(char *, int)
+ unsigned alarm(unsigned)
+ int chdir(char *)
+ int chown(char *, uid_t, gid_t)
+ int close(int)
+ size_t confstr(int, char *, size_t)
+ char *crypt(char *, char *)
+ char *ctermid(char *)
+ int dup(int)
+ int dup2(int, int)
+ void encrypt(char[64], int)
+ int execl(char *, char *, ...)
+ int execle(char *, char *, ...)
+ int execlp(char *, char *, ...)
+ int execv(char *, char *[])
+ int execve(char *, char *[], char *[])
+ int execvp(char *, char *[])
+ void _exit(int)
+ int fchown(int, uid_t, gid_t)
+ int fchdir(int)
+ int fdatasync(int)
+ pid_t fork()
+ long fpathconf(int, int)
+ int fsync(int)
+ int ftruncate(int, off_t)
+ char *getcwd(char *, size_t)
+ gid_t getegid()
+ uid_t geteuid()
+ gid_t getgid()
+ int getgroups(int, gid_t [])
+ long gethostid()
+ int gethostname(char *, size_t)
+ char *getlogin()
+ int getlogin_r(char *, size_t)
+ int getopt(int, char * [], char *)
+ pid_t getpgid(pid_t)
+ pid_t getpgrp()
+ pid_t getpid()
+ pid_t getppid()
+ pid_t getsid(pid_t)
+ uid_t getuid()
+ char *getwd(char *)
+ int isatty(int)
+ int lchown(char *, uid_t, gid_t)
+ int link(char *, char *)
+ int lockf(int, int, off_t)
+ off_t lseek(int, off_t, int)
+ int nice(int)
+ long pathconf(char *, int)
+ int pause()
+ int pipe(int [2])
+ ssize_t pread(int, void *, size_t, off_t)
+ ssize_t pwrite(int, void *, size_t, off_t)
+ ssize_t read(int, void *, size_t)
+ ssize_t readlink(char *, char *, size_t)
+ int rmdir(char *)
+ int setegid(gid_t)
+ int seteuid(uid_t)
+ int setgid(gid_t)
+ int setpgid(pid_t, pid_t)
+ pid_t setpgrp()
+ int setregid(gid_t, gid_t)
+ int setreuid(uid_t, uid_t)
+ pid_t setsid()
+ int setuid(uid_t)
+ unsigned sleep(unsigned)
+ void swab(void *, void *, ssize_t)
+ int symlink(char *, char *)
+ void sync()
+ long sysconf(int)
+ pid_t tcgetpgrp(int)
+ int tcsetpgrp(int, pid_t)
+ int truncate(char *, off_t)
+ char *ttyname(int)
+ int ttyname_r(int, char *, size_t)
+ useconds_t ualarm(useconds_t, useconds_t)
+ int unlink(char *)
+ int usleep(useconds_t)
+ pid_t vfork()
+ ssize_t write(int, void *, size_t)
+ char *optarg
+ int optind
+ int opterr
+ int optopt
--- /dev/null
+from libc.stdio cimport *
+from posix.unistd cimport *
+from posix.fcntl cimport *
+
+cdef int noisy_function() except -1:
+ cdef int ret = 0
+ ret = printf(b"0123456789\n", 0)
+ assert ret == 11
+ ret = fflush(stdout)
+ assert ret == 0
+ ret = fprintf(stdout, b"0123456789\n", 0)
+ assert ret == 11
+ ret = fflush(stdout)
+ assert ret == 0
+ ret = write(STDOUT_FILENO, b"0123456789\n", 11)
+ assert ret == 11
+ return 0
+
+
+def test_silent_stdout():
+ """
+ >>> test_silent_stdout()
+ """
+ cdef int ret
+ cdef int stdout_save, dev_null
+ stdout_save = dup(STDOUT_FILENO)
+ assert stdout_save != -1
+ dev_null = open(b"/dev/null", O_WRONLY, 0)
+ assert dev_null != -1
+ ret = dup2(dev_null, STDOUT_FILENO)
+ assert ret == STDOUT_FILENO
+ ret = close(dev_null)
+ assert ret == 0
+ try:
+ noisy_function()
+ finally:
+ ret = dup2(stdout_save, STDOUT_FILENO)
+ assert ret == STDOUT_FILENO
+ ret = close(stdout_save)
+ assert ret == 0
+
+cdef class silent_fd:
+
+ cdef int fd_save, fd
+
+ def __cinit__(self, int fd=-1):
+ self.fd_save = -1
+ self.fd = STDOUT_FILENO
+ if fd != -1:
+ self.fd = fd
+
+ def __enter__(self):
+ cdef int ret = 0, dev_null = -1
+ assert self.fd_save == -1
+ dev_null = open(b"/dev/null", O_WRONLY, 0)
+ assert dev_null != -1
+ try:
+ self.fd_save = dup(self.fd)
+ assert self.fd_save != -1
+ try:
+ ret = dup2(dev_null, self.fd)
+ assert ret != -1
+ except:
+ ret = close(self.fd_save)
+ self.fd_save = -1
+ finally:
+ ret = close(dev_null)
+
+ def __exit__(self, t, v, tb):
+ cdef int ret = 0
+ if self.fd_save != -1:
+ ret = dup2(self.fd_save, self.fd)
+ assert ret == self.fd
+ ret = close(self.fd_save)
+ assert ret == 0
+ self.fd_save = -1
+ return None
+
+def test_silent_stdout_ctxmanager():
+ """
+ >> test_silent_stdout_ctxmanager()
+ """
+ with silent_fd():
+ noisy_function()
+ try:
+ with silent_fd():
+ noisy_function()
+ raise RuntimeError
+ except RuntimeError:
+ pass
+ with silent_fd(STDOUT_FILENO):
+ noisy_function()