diff --git a/pep-0466/test_cloexec.py b/pep-0466/test_cloexec.py new file mode 100644 index 000000000..88f5a0bd1 --- /dev/null +++ b/pep-0466/test_cloexec.py @@ -0,0 +1,50 @@ +import os, fcntl, sys, errno + +def get_cloexec(fd): + try: + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + return bool(flags & fcntl.FD_CLOEXEC) + except IOError as err: + if err.errno == errno.EBADF: + return '' + else: + return str(err) + +def set_cloexec(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFD) + flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(fd, fcntl.F_SETFD, flags) + +def main(): + f = open(__file__, "rb") + fd = f.fileno() + print("initial state: fd=%s, cloexec=%s" % (fd, get_cloexec(fd))) + + + pid = os.fork() + if not pid: + set_cloexec(fd) + print("child process after fork, set cloexec: cloexec=%s" % get_cloexec(fd)) + child_argv = [sys.executable, __file__, str(fd), + 'child process after exec'] + os.execv(child_argv[0], child_argv) + + os.waitpid(pid, 0) + print("parent process after fork: cloexec=%s" % get_cloexec(fd)) + child_argv = [sys.executable, __file__, str(fd), + 'parent process after exec'] + os.execv(child_argv[0], child_argv) + +def after_exec(): + fd = int(sys.argv[1]) + name = sys.argv[2] + print("%s: fd=%s, cloexec=%s" + % (name, fd, get_cloexec(fd))) + sys.exit() + +if __name__ == "__main__": + if len(sys.argv) == 1: + main() + else: + after_exec() +