Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import os
- import os.path
- import fcntl
- import ctypes
- from ctypes.util import find_library
- import re
- libc = None
- F_CLOSEM = None
- strategy = None
- __all__ = ('closefrom', 'closefrom_impl')
- def closefrom(fd):
- """
- A portable Python implementation-shim for the closefrom(2) system call,
- using various other OS's equivalents of the same wherever available.
- Should work on most BSDs, Linux, and OS X at least. Raises a
- NotImplementedError if no implementation strategy works.
- """
- fd = int(fd)
- global strategy
- if not strategy: strategy = closefrom_impl()
- if strategy == 'closefrom':
- return libc.closefrom(fd)
- elif strategy == 'fclosem':
- return fcntl.fcntl(fd, F_CLOSEM, 0)
- elif strategy == 'devfd':
- return closefrom_dir('/dev/fd', fd)
- elif strategy == 'procfs':
- return closefrom_dir('/proc/%d/fd' % os.getpid(), fd)
- else:
- raise NotImplementedError('closefrom is not supported on this platform')
- def closefrom_dir(dir, fd):
- fds = (int(fd) for fd in os.listdir(dir))
- for open_fd in fds:
- try:
- print(open_fd)
- if open_fd >= fd: os.close(open_fd)
- except OSError: pass
- def closefrom_impl():
- """
- Detects available methods for implementing closefrom(2), and returns
- a string value representing the one that closefrom will use.
- Return values, in order of preference:
- - closefrom
- closefrom(2) directly (FreeBSD)
- - fclosem
- The F_CLOSEM fcntl, functionally equivalent to closefrom (NetBSD)
- - devfd
- The /dev/fd/ directory will be listed for the necessary file
- descriptor numbers (OS X)
- - procfs
- Same as devfd except that the /proc/<pid>/fd/ directory is used
- instead (Linux)
- - None
- No implementation available
- """
- global libc
- load_libc()
- if libc:
- try:
- if callable(libc.closefrom):
- return 'closefrom'
- except AttributeError: pass
- global F_CLOSEM
- F_CLOSEM = fclosem_constant()
- if F_CLOSEM:
- return 'fclosem'
- if os.path.isdir('/dev/fd'):
- return 'devfd'
- elif os.path.isdir('/proc/%d/fd' % os.getpid()):
- return 'procfs'
- return None
- def fclosem_constant():
- try:
- return fcntl.F_CLOSEM
- except AttributeError: pass
- fclosem_re = re.compile(rb"^#define\s+F_CLOSEM\s+(\d)+\s")
- if os.path.isfile('/usr/include/fcntl.h'):
- with open('/usr/include/fcntl.h', 'rb') as header_file:
- for line in header_file:
- match = fclosem_re.match(line)
- if match:
- return int(match.group(1))
- return None
- def load_libc():
- global libc
- libc_name = find_library('c')
- if libc_name:
- try:
- libc = ctypes.cdll.LoadLibrary(libc_name)
- except OSError: return None
- else:
- return None
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement