0001 """Temporary files. 0002 0003 This module provides generic, low- and high-level interfaces for 0004 creating temporary files and directories. The interfaces listed 0005 as "safe" just below can be used without fear of race conditions. 0006 Those listed as "unsafe" cannot, and are provided for backward 0007 compatibility only. 0008 0009 This module also provides some data items to the user: 0010 0011 TMP_MAX - maximum number of names that will be tried before 0012 giving up. 0013 template - the default prefix for all temporary names. 0014 You may change this to control the default prefix. 0015 tempdir - If this is set to a string before the first use of 0016 any routine from this module, it will be considered as 0017 another candidate location to store temporary files. 0018 """ 0019 0020 __all__ = [ 0021 "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces 0022 "mkstemp", "mkdtemp", # low level safe interfaces 0023 "mktemp", # deprecated unsafe interface 0024 "TMP_MAX", "gettempprefix", # constants 0025 "tempdir", "gettempdir" 0026 ] 0027 0028 0029 # Imports. 0030 0031 import os as _os 0032 import errno as _errno 0033 from random import Random as _Random 0034 0035 if _os.name == 'mac': 0036 import Carbon.Folder as _Folder 0037 import Carbon.Folders as _Folders 0038 0039 try: 0040 import fcntl as _fcntl 0041 except ImportError: 0042 def _set_cloexec(fd): 0043 pass 0044 else: 0045 def _set_cloexec(fd): 0046 try: 0047 flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0) 0048 except IOError: 0049 pass 0050 else: 0051 # flags read successfully, modify 0052 flags |= _fcntl.FD_CLOEXEC 0053 _fcntl.fcntl(fd, _fcntl.F_SETFD, flags) 0054 0055 0056 try: 0057 import thread as _thread 0058 except ImportError: 0059 import dummy_thread as _thread 0060 _allocate_lock = _thread.allocate_lock 0061 0062 _text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL 0063 if hasattr(_os, 'O_NOINHERIT'): 0064 _text_openflags |= _os.O_NOINHERIT 0065 if hasattr(_os, 'O_NOFOLLOW'): 0066 _text_openflags |= _os.O_NOFOLLOW 0067 0068 _bin_openflags = _text_openflags 0069 if hasattr(_os, 'O_BINARY'): 0070 _bin_openflags |= _os.O_BINARY 0071 0072 if hasattr(_os, 'TMP_MAX'): 0073 TMP_MAX = _os.TMP_MAX 0074 else: 0075 TMP_MAX = 10000 0076 0077 template = "tmp" 0078 0079 tempdir = None 0080 0081 # Internal routines. 0082 0083 _once_lock = _allocate_lock() 0084 0085 if hasattr(_os, "lstat"): 0086 _stat = _os.lstat 0087 elif hasattr(_os, "stat"): 0088 _stat = _os.stat 0089 else: 0090 # Fallback. All we need is something that raises os.error if the 0091 # file doesn't exist. 0092 def _stat(fn): 0093 try: 0094 f = open(fn) 0095 except IOError: 0096 raise _os.error 0097 f.close() 0098 0099 def _exists(fn): 0100 try: 0101 _stat(fn) 0102 except _os.error: 0103 return False 0104 else: 0105 return True 0106 0107 class _RandomNameSequence: 0108 """An instance of _RandomNameSequence generates an endless 0109 sequence of unpredictable strings which can safely be incorporated 0110 into file names. Each string is six characters long. Multiple 0111 threads can safely use the same instance at the same time. 0112 0113 _RandomNameSequence is an iterator.""" 0114 0115 characters = ("abcdefghijklmnopqrstuvwxyz" + 0116 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 0117 "0123456789-_") 0118 0119 def __init__(self): 0120 self.mutex = _allocate_lock() 0121 self.rng = _Random() 0122 self.normcase = _os.path.normcase 0123 0124 def __iter__(self): 0125 return self 0126 0127 def next(self): 0128 m = self.mutex 0129 c = self.characters 0130 choose = self.rng.choice 0131 0132 m.acquire() 0133 try: 0134 letters = [choose(c) for dummy in "123456"] 0135 finally: 0136 m.release() 0137 0138 return self.normcase(''.join(letters)) 0139 0140 def _candidate_tempdir_list(): 0141 """Generate a list of candidate temporary directories which 0142 _get_default_tempdir will try.""" 0143 0144 dirlist = [] 0145 0146 # First, try the environment. 0147 for envname in 'TMPDIR', 'TEMP', 'TMP': 0148 dirname = _os.getenv(envname) 0149 if dirname: dirlist.append(dirname) 0150 0151 # Failing that, try OS-specific locations. 0152 if _os.name == 'mac': 0153 try: 0154 fsr = _Folder.FSFindFolder(_Folders.kOnSystemDisk, 0155 _Folders.kTemporaryFolderType, 1) 0156 dirname = fsr.as_pathname() 0157 dirlist.append(dirname) 0158 except _Folder.error: 0159 pass 0160 elif _os.name == 'riscos': 0161 dirname = _os.getenv('Wimp$ScrapDir') 0162 if dirname: dirlist.append(dirname) 0163 elif _os.name == 'nt': 0164 dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) 0165 else: 0166 dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) 0167 0168 # As a last resort, the current directory. 0169 try: 0170 dirlist.append(_os.getcwd()) 0171 except (AttributeError, _os.error): 0172 dirlist.append(_os.curdir) 0173 0174 return dirlist 0175 0176 def _get_default_tempdir(): 0177 """Calculate the default directory to use for temporary files. 0178 This routine should be called exactly once. 0179 0180 We determine whether or not a candidate temp dir is usable by 0181 trying to create and write to a file in that directory. If this 0182 is successful, the test file is deleted. To prevent denial of 0183 service, the name of the test file must be randomized.""" 0184 0185 namer = _RandomNameSequence() 0186 dirlist = _candidate_tempdir_list() 0187 flags = _text_openflags 0188 0189 for dir in dirlist: 0190 if dir != _os.curdir: 0191 dir = _os.path.normcase(_os.path.abspath(dir)) 0192 # Try only a few names per directory. 0193 for seq in xrange(100): 0194 name = namer.next() 0195 filename = _os.path.join(dir, name) 0196 try: 0197 fd = _os.open(filename, flags, 0600) 0198 fp = _os.fdopen(fd, 'w') 0199 fp.write('blat') 0200 fp.close() 0201 _os.unlink(filename) 0202 del fp, fd 0203 return dir 0204 except (OSError, IOError), e: 0205 if e[0] != _errno.EEXIST: 0206 break # no point trying more names in this directory 0207 pass 0208 raise IOError, (_errno.ENOENT, 0209 ("No usable temporary directory found in %s" % dirlist)) 0210 0211 _name_sequence = None 0212 0213 def _get_candidate_names(): 0214 """Common setup sequence for all user-callable interfaces.""" 0215 0216 global _name_sequence 0217 if _name_sequence is None: 0218 _once_lock.acquire() 0219 try: 0220 if _name_sequence is None: 0221 _name_sequence = _RandomNameSequence() 0222 finally: 0223 _once_lock.release() 0224 return _name_sequence 0225 0226 0227 def _mkstemp_inner(dir, pre, suf, flags): 0228 """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" 0229 0230 names = _get_candidate_names() 0231 0232 for seq in xrange(TMP_MAX): 0233 name = names.next() 0234 file = _os.path.join(dir, pre + name + suf) 0235 try: 0236 fd = _os.open(file, flags, 0600) 0237 _set_cloexec(fd) 0238 return (fd, _os.path.abspath(file)) 0239 except OSError, e: 0240 if e.errno == _errno.EEXIST: 0241 continue # try again 0242 raise 0243 0244 raise IOError, (_errno.EEXIST, "No usable temporary file name found") 0245 0246 0247 # User visible interfaces. 0248 0249 def gettempprefix(): 0250 """Accessor for tempdir.template.""" 0251 return template 0252 0253 tempdir = None 0254 0255 def gettempdir(): 0256 """Accessor for tempdir.tempdir.""" 0257 global tempdir 0258 if tempdir is None: 0259 _once_lock.acquire() 0260 try: 0261 if tempdir is None: 0262 tempdir = _get_default_tempdir() 0263 finally: 0264 _once_lock.release() 0265 return tempdir 0266 0267 def mkstemp(suffix="", prefix=template, dir=None, text=False): 0268 """mkstemp([suffix, [prefix, [dir, [text]]]]) 0269 User-callable function to create and return a unique temporary 0270 file. The return value is a pair (fd, name) where fd is the 0271 file descriptor returned by os.open, and name is the filename. 0272 0273 If 'suffix' is specified, the file name will end with that suffix, 0274 otherwise there will be no suffix. 0275 0276 If 'prefix' is specified, the file name will begin with that prefix, 0277 otherwise a default prefix is used. 0278 0279 If 'dir' is specified, the file will be created in that directory, 0280 otherwise a default directory is used. 0281 0282 If 'text' is specified and true, the file is opened in text 0283 mode. Else (the default) the file is opened in binary mode. On 0284 some operating systems, this makes no difference. 0285 0286 The file is readable and writable only by the creating user ID. 0287 If the operating system uses permission bits to indicate whether a 0288 file is executable, the file is executable by no one. The file 0289 descriptor is not inherited by children of this process. 0290 0291 Caller is responsible for deleting the file when done with it. 0292 """ 0293 0294 if dir is None: 0295 dir = gettempdir() 0296 0297 if text: 0298 flags = _text_openflags 0299 else: 0300 flags = _bin_openflags 0301 0302 return _mkstemp_inner(dir, prefix, suffix, flags) 0303 0304 0305 def mkdtemp(suffix="", prefix=template, dir=None): 0306 """mkdtemp([suffix, [prefix, [dir]]]) 0307 User-callable function to create and return a unique temporary 0308 directory. The return value is the pathname of the directory. 0309 0310 Arguments are as for mkstemp, except that the 'text' argument is 0311 not accepted. 0312 0313 The directory is readable, writable, and searchable only by the 0314 creating user. 0315 0316 Caller is responsible for deleting the directory when done with it. 0317 """ 0318 0319 if dir is None: 0320 dir = gettempdir() 0321 0322 names = _get_candidate_names() 0323 0324 for seq in xrange(TMP_MAX): 0325 name = names.next() 0326 file = _os.path.join(dir, prefix + name + suffix) 0327 try: 0328 _os.mkdir(file, 0700) 0329 return file 0330 except OSError, e: 0331 if e.errno == _errno.EEXIST: 0332 continue # try again 0333 raise 0334 0335 raise IOError, (_errno.EEXIST, "No usable temporary directory name found") 0336 0337 def mktemp(suffix="", prefix=template, dir=None): 0338 """mktemp([suffix, [prefix, [dir]]]) 0339 User-callable function to return a unique temporary file name. The 0340 file is not created. 0341 0342 Arguments are as for mkstemp, except that the 'text' argument is 0343 not accepted. 0344 0345 This function is unsafe and should not be used. The file name 0346 refers to a file that did not exist at some point, but by the time 0347 you get around to creating it, someone else may have beaten you to 0348 the punch. 0349 """ 0350 0351 ## from warnings import warn as _warn 0352 ## _warn("mktemp is a potential security risk to your program", 0353 ## RuntimeWarning, stacklevel=2) 0354 0355 if dir is None: 0356 dir = gettempdir() 0357 0358 names = _get_candidate_names() 0359 for seq in xrange(TMP_MAX): 0360 name = names.next() 0361 file = _os.path.join(dir, prefix + name + suffix) 0362 if not _exists(file): 0363 return file 0364 0365 raise IOError, (_errno.EEXIST, "No usable temporary filename found") 0366 0367 class _TemporaryFileWrapper: 0368 """Temporary file wrapper 0369 0370 This class provides a wrapper around files opened for 0371 temporary use. In particular, it seeks to automatically 0372 remove the file when it is no longer needed. 0373 """ 0374 0375 def __init__(self, file, name): 0376 self.file = file 0377 self.name = name 0378 self.close_called = False 0379 0380 def __getattr__(self, name): 0381 file = self.__dict__['file'] 0382 a = getattr(file, name) 0383 if type(a) != type(0): 0384 setattr(self, name, a) 0385 return a 0386 0387 # NT provides delete-on-close as a primitive, so we don't need 0388 # the wrapper to do anything special. We still use it so that 0389 # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. 0390 if _os.name != 'nt': 0391 0392 # Cache the unlinker so we don't get spurious errors at 0393 # shutdown when the module-level "os" is None'd out. Note 0394 # that this must be referenced as self.unlink, because the 0395 # name TemporaryFileWrapper may also get None'd out before 0396 # __del__ is called. 0397 unlink = _os.unlink 0398 0399 def close(self): 0400 if not self.close_called: 0401 self.close_called = True 0402 self.file.close() 0403 self.unlink(self.name) 0404 0405 def __del__(self): 0406 self.close() 0407 0408 def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="", 0409 prefix=template, dir=None): 0410 """Create and return a temporary file. 0411 Arguments: 0412 'prefix', 'suffix', 'dir' -- as for mkstemp. 0413 'mode' -- the mode argument to os.fdopen (default "w+b"). 0414 'bufsize' -- the buffer size argument to os.fdopen (default -1). 0415 The file is created as mkstemp() would do it. 0416 0417 Returns a file object; the name of the file is accessible as 0418 file.name. The file will be automatically deleted when it is 0419 closed. 0420 """ 0421 0422 if dir is None: 0423 dir = gettempdir() 0424 0425 if 'b' in mode: 0426 flags = _bin_openflags 0427 else: 0428 flags = _text_openflags 0429 0430 # Setting O_TEMPORARY in the flags causes the OS to delete 0431 # the file when it is closed. This is only supported by Windows. 0432 if _os.name == 'nt': 0433 flags |= _os.O_TEMPORARY 0434 0435 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 0436 file = _os.fdopen(fd, mode, bufsize) 0437 return _TemporaryFileWrapper(file, name) 0438 0439 if _os.name != 'posix' or _os.sys.platform == 'cygwin': 0440 # On non-POSIX and Cygwin systems, assume that we cannot unlink a file 0441 # while it is open. 0442 TemporaryFile = NamedTemporaryFile 0443 0444 else: 0445 def TemporaryFile(mode='w+b', bufsize=-1, suffix="", 0446 prefix=template, dir=None): 0447 """Create and return a temporary file. 0448 Arguments: 0449 'prefix', 'suffix', 'directory' -- as for mkstemp. 0450 'mode' -- the mode argument to os.fdopen (default "w+b"). 0451 'bufsize' -- the buffer size argument to os.fdopen (default -1). 0452 The file is created as mkstemp() would do it. 0453 0454 Returns a file object. The file has no name, and will cease to 0455 exist when it is closed. 0456 """ 0457 0458 if dir is None: 0459 dir = gettempdir() 0460 0461 if 'b' in mode: 0462 flags = _bin_openflags 0463 else: 0464 flags = _text_openflags 0465 0466 (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 0467 try: 0468 _os.unlink(name) 0469 return _os.fdopen(fd, mode, bufsize) 0470 except: 0471 _os.close(fd) 0472 raise 0473
Generated by PyXR 0.9.4