#NEWLINE# def open_files( pid = None , close_unused = True ) : #NEWLINE# #INDENT# '\n    Return a dict of open files for the given process.\n    The key of the dict is the file descriptor (a number).\n    \n    If PID is not specified, the PID of the current program is used.\n    Only regular open files are returned.\n    \n    If close_unused is True, do garbage collection prior to getting the list\n    of open files. This makes open_files() more reliable, as files which are\n    no longer reachable or used, but not yet closed by the resource manager.\n    \n    This function relies on the external `lsof` program.\n    This function may raise an OSError.\n    ' #NEWLINE# if ( pid is None ) : #NEWLINE# #INDENT# pid = os . getpid ( ) #NEWLINE# #UNINDENT# if close_unused : #NEWLINE# #INDENT# gc . collect ( ) #NEWLINE# #UNINDENT# command = [ 'lsof' , '-nlP' , '-b' , '-w' , '-p' , str ( pid ) , '-F' , 'ftn' ] #NEWLINE# env = dict ( os . environ ) . copy ( ) #NEWLINE# env [ 'LC_ALL' ] = 'UTF-8' #NEWLINE# output = subprocess . Popen ( command , stdout = subprocess . PIPE , env = env ) . communicate ( ) [ 0 ] #NEWLINE# output = output . decode ( 'utf-8' ) . split ( '\n' ) #NEWLINE# files = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# state = { #NEWLINE# #INDENT# 'f' : '' , #NEWLINE# 't' : '' , #NEWLINE# #UNINDENT# } #NEWLINE# for line in output : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# ( linetype , line ) = ( line [ 0 ] , line [ 1 : ] ) #NEWLINE# #UNINDENT# except IndexError : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# state [ linetype ] = line #NEWLINE# if ( linetype == 'n' ) : #NEWLINE# #INDENT# if ( ( state [ 't' ] == 'REG' ) and state [ 'f' ] . isdigit ( ) ) : #NEWLINE# #INDENT# files [ int ( state [ 'f' ] ) ] = line #NEWLINE# state = { #NEWLINE# #INDENT# 'f' : '' , #NEWLINE# 't' : '' , #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return files