Advertisement
Guest User

Untitled

a guest
Jan 29th, 2015
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.94 KB | None | 0 0
  1. import os
  2. import os.path
  3. import fcntl
  4. import ctypes
  5. from ctypes.util import find_library
  6. import re
  7.  
  8. libc = None
  9. F_CLOSEM = None
  10. strategy = None
  11.  
  12. __all__ = ('closefrom', 'closefrom_impl')
  13.  
  14.  
  15. def closefrom(fd):
  16. """
  17. A portable Python implementation-shim for the closefrom(2) system call,
  18. using various other OS's equivalents of the same wherever available.
  19. Should work on most BSDs, Linux, and OS X at least. Raises a
  20. NotImplementedError if no implementation strategy works.
  21. """
  22. fd = int(fd)
  23.  
  24. global strategy
  25. if not strategy: strategy = closefrom_impl()
  26.  
  27. if strategy == 'closefrom':
  28. return libc.closefrom(fd)
  29. elif strategy == 'fclosem':
  30. return fcntl.fcntl(fd, F_CLOSEM, 0)
  31. elif strategy == 'devfd':
  32. return closefrom_dir('/dev/fd', fd)
  33. elif strategy == 'procfs':
  34. return closefrom_dir('/proc/%d/fd' % os.getpid(), fd)
  35. else:
  36. raise NotImplementedError('closefrom is not supported on this platform')
  37.  
  38. def closefrom_dir(dir, fd):
  39. fds = (int(fd) for fd in os.listdir(dir))
  40. for open_fd in fds:
  41. try:
  42. print(open_fd)
  43. if open_fd >= fd: os.close(open_fd)
  44. except OSError: pass
  45.  
  46. def closefrom_impl():
  47. """
  48. Detects available methods for implementing closefrom(2), and returns
  49. a string value representing the one that closefrom will use.
  50.  
  51. Return values, in order of preference:
  52. - closefrom
  53. closefrom(2) directly (FreeBSD)
  54. - fclosem
  55. The F_CLOSEM fcntl, functionally equivalent to closefrom (NetBSD)
  56. - devfd
  57. The /dev/fd/ directory will be listed for the necessary file
  58. descriptor numbers (OS X)
  59. - procfs
  60. Same as devfd except that the /proc/<pid>/fd/ directory is used
  61. instead (Linux)
  62. - None
  63. No implementation available
  64. """
  65.  
  66. global libc
  67. load_libc()
  68.  
  69. if libc:
  70. try:
  71. if callable(libc.closefrom):
  72. return 'closefrom'
  73. except AttributeError: pass
  74.  
  75. global F_CLOSEM
  76. F_CLOSEM = fclosem_constant()
  77. if F_CLOSEM:
  78. return 'fclosem'
  79.  
  80. if os.path.isdir('/dev/fd'):
  81. return 'devfd'
  82. elif os.path.isdir('/proc/%d/fd' % os.getpid()):
  83. return 'procfs'
  84.  
  85. return None
  86.  
  87. def fclosem_constant():
  88. try:
  89. return fcntl.F_CLOSEM
  90. except AttributeError: pass
  91.  
  92. fclosem_re = re.compile(rb"^#define\s+F_CLOSEM\s+(\d)+\s")
  93. if os.path.isfile('/usr/include/fcntl.h'):
  94. with open('/usr/include/fcntl.h', 'rb') as header_file:
  95. for line in header_file:
  96. match = fclosem_re.match(line)
  97. if match:
  98. return int(match.group(1))
  99.  
  100. return None
  101.  
  102. def load_libc():
  103. global libc
  104.  
  105. libc_name = find_library('c')
  106. if libc_name:
  107. try:
  108. libc = ctypes.cdll.LoadLibrary(libc_name)
  109. except OSError: return None
  110. else:
  111. return None
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement