source file: /System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/tempfile.py
file stats: 213 lines, 50 executed: 23.5% covered
1. """Temporary files. 2. 3. This module provides generic, low- and high-level interfaces for 4. creating temporary files and directories. The interfaces listed 5. as "safe" just below can be used without fear of race conditions. 6. Those listed as "unsafe" cannot, and are provided for backward 7. compatibility only. 8. 9. This module also provides some data items to the user: 10. 11. TMP_MAX - maximum number of names that will be tried before 12. giving up. 13. template - the default prefix for all temporary names. 14. You may change this to control the default prefix. 15. tempdir - If this is set to a string before the first use of 16. any routine from this module, it will be considered as 17. another candidate location to store temporary files. 18. """ 19. 20. __all__ = [ 21. "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces 22. "mkstemp", "mkdtemp", # low level safe interfaces 23. "mktemp", # deprecated unsafe interface 24. "TMP_MAX", "gettempprefix", # constants 25. "tempdir", "gettempdir" 26. ] 27. 28. 29. # Imports. 30. 31. import os as _os 32. import errno as _errno 33. from random import Random as _Random 34. 35. if _os.name == 'mac': 36. import Carbon.Folder as _Folder 37. import Carbon.Folders as _Folders 38. 39. try: 40. import fcntl as _fcntl 41. # If PYTHONCASEOK is set on Windows, stinking FCNTL.py gets 42. # imported, and we don't get an ImportError then. Provoke 43. # an AttributeError instead in that case. 44. _fcntl.fcntl 45. except (ImportError, AttributeError): 46. def _set_cloexec(fd): 47. pass 48. else: 49. def _set_cloexec(fd): 50. try: flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0) 51. except IOError: pass 52. else: 53. # flags read successfully, modify 54. flags |= _fcntl.FD_CLOEXEC 55. _fcntl.fcntl(fd, _fcntl.F_SETFD, flags) 56. 57. 58. try: 59. import thread as _thread 60. except ImportError: 61. import dummy_thread as _thread 62. _allocate_lock = _thread.allocate_lock 63. 64. _text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL 65. if hasattr(_os, 'O_NOINHERIT'): 66. _text_openflags |= _os.O_NOINHERIT 67. if hasattr(_os, 'O_NOFOLLOW'): 68. _text_openflags |= _os.O_NOFOLLOW 69. 70. _bin_openflags = _text_openflags 71. if hasattr(_os, 'O_BINARY'): 72. _bin_openflags |= _os.O_BINARY 73. 74. if hasattr(_os, 'TMP_MAX'): 75. TMP_MAX = _os.TMP_MAX 76. else: 77. TMP_MAX = 10000 78. 79. template = "tmp" 80. 81. tempdir = None 82. 83. # Internal routines. 84. 85. _once_lock = _allocate_lock() 86. 87. class _RandomNameSequence: 88. """An instance of _RandomNameSequence generates an endless 89. sequence of unpredictable strings which can safely be incorporated 90. into file names. Each string is six characters long. Multiple 91. threads can safely use the same instance at the same time. 92. 93. _RandomNameSequence is an iterator.""" 94. 95. characters = ("abcdefghijklmnopqrstuvwxyz" + 96. "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 97. "0123456789-_") 98. 99. def __init__(self): 100. self.mutex = _allocate_lock() 101. self.rng = _Random() 102. self.normcase = _os.path.normcase 103. 104. def __iter__(self): 105. return self 106. 107. def next(self): 108. m = self.mutex 109. c = self.characters 110. choose = self.rng.choice 111. 112. m.acquire() 113. try: 114. letters = [choose(c) for dummy in "123456"] 115. finally: 116. m.release() 117. 118. return self.normcase(''.join(letters)) 119. 120. def _candidate_tempdir_list(): 121. """Generate a list of candidate temporary directories which 122. _get_default_tempdir will try.""" 123. 124. dirlist = [] 125. 126. # First, try the environment. 127. for envname in 'TMPDIR', 'TEMP', 'TMP': 128. dirname = _os.getenv(envname) 129. if dirname: dirlist.append(dirname) 130. 131. # Failing that, try OS-specific locations. 132. if _os.name == 'mac': 133. try: 134. fsr = _Folder.FSFindFolder(_Folders.kOnSystemDisk, 135. _Folders.kTemporaryFolderType, 1) 136. dirname = fsr.as_pathname() 137. dirlist.append(dirname) 138. except _Folder.error: 139. pass 140. elif _os.name == 'riscos': 141. dirname = _os.getenv('Wimp$ScrapDir') 142. if dirname: dirlist.append(dirname) 143. elif _os.name == 'nt': 144. dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) 145. else: 146. dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) 147. 148. # As a last resort, the current directory. 149. try: 150. dirlist.append(_os.getcwd()) 151. except (AttributeError, _os.error): 152. dirlist.append(_os.curdir) 153. 154. return dirlist 155. 156. def _get_default_tempdir(): 157. """Calculate the default directory to use for temporary files. 158. This routine should be called exactly once. 159. 160. We determine whether or not a candidate temp dir is usable by 161. trying to create and write to a file in that directory. If this 162. is successful, the test file is deleted. To prevent denial of 163. service, the name of the test file must be randomized.""" 164. 165. namer = _RandomNameSequence() 166. dirlist = _candidate_tempdir_list() 167. flags = _text_openflags 168. 169. for dir in dirlist: 170. if dir != _os.curdir: 171. dir = _os.path.normcase(_os.path.abspath(dir)) 172. # Try only a few names per directory. 173. for seq in xrange(100): 174. name = namer.next() 175. filename = _os.path.join(dir, name) 176. try: 177. fd = _os.open(filename, flags, 0600) 178. fp = _os.fdopen(fd, 'w') 179. fp.write('blat') 180. fp.close() 181. _os.unlink(filename) 182. del fp, fd 183. return dir 184. except (OSError, IOError), e: 185. if e[0] != _errno.EEXIST: 186. break # no point trying more names in this directory 187. pass 188. raise IOError, (_errno.ENOENT, 189. ("No usable temporary directory found in %s" % dirlist)) 190. 191. _name_sequence = None 192. 193. def _get_candidate_names(): 194. """Common setup sequence for all user-callable interfaces.""" 195. 196. global _name_sequence 197. if _name_sequence is None: 198. _once_lock.acquire() 199. try: 200. if _name_sequence is None: 201. _name_sequence = _RandomNameSequence() 202. finally: 203. _once_lock.release() 204. return _name_sequence 205. 206. 207. def _mkstemp_inner(dir, pre, suf, flags): 208. """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" 209. 210. names = _get_candidate_names() 211. 212. for seq in xrange(TMP_MAX): 213. name = names.next() 214. file = _os.path.join(dir, pre + name + suf) 215. try: 216. fd = _os.open(file, flags, 0600) 217. _set_cloexec(fd) 218. return (fd, file) 219. except OSError, e: 220. if e.errno == _errno.EEXIST: 221. continue # try again 222. raise 223. 224. raise IOError, (_errno.EEXIST, "No usable temporary file name found") 225. 226. 227. # User visible interfaces. 228. 229. def gettempprefix(): 230. """Accessor for tempdir.template.""" 231. return template 232. 233. tempdir = None 234. 235. def gettempdir(): 236. """Accessor for tempdir.tempdir.""" 237. global tempdir 238. if tempdir is None: 239. _once_lock.acquire() 240. try: 241. if tempdir is None: 242. tempdir = _get_default_tempdir() 243. finally: 244. _once_lock.release() 245. return tempdir 246. 247. def mkstemp(suffix="", prefix=template, dir=None, text=False): 248. """mkstemp([suffix, [prefix, [dir, [text]]]]) 249. User-callable function to create and return a unique temporary 250. file. The return value is a pair (fd, name) where fd is the 251. file descriptor returned by os.open, and name is the filename. 252. 253. If 'suffix' is specified, the file name will end with that suffix, 254. otherwise there will be no suffix. 255. 256. If 'prefix' is specified, the file name will begin with that prefix, 257. otherwise a default prefix is used. 258. 259. If 'dir' is specified, the file will be created in that directory, 260. otherwise a default directory is used. 261. 262. If 'text' is specified and true, the file is opened in text 263. mode. Else (the default) the file is opened in binary mode. On 264. some operating systems, this makes no difference. 265. 266. The file is readable and writable only by the creating user ID. 267. If the operating system uses permission bits to indicate whether a 268. file is executable, the file is executable by no one. The file 269. descriptor is not inherited by children of this process. 270. 271. Caller is responsible for deleting the file when done with it. 272. """ 273. 274. if dir is None: 275. dir = gettempdir() 276. 277. if text: 278. flags = _text_openflags 279. else: 280. flags = _bin_openflags 281. 282. return _mkstemp_inner(dir, prefix, suffix, flags) 283. 284. 285. def mkdtemp(suffix="", prefix=template, dir=None): 286. """mkdtemp([suffix, [prefix, [dir]]]) 287. User-callable function to create and return a unique temporary 288. directory. The return value is the pathname of the directory. 289. 290. Arguments are as for mkstemp, except that the 'text' argument is 291. not accepted. 292. 293. The directory is readable, writable, and searchable only by the 294. creating user. 295. 296. Caller is responsible for deleting the directory when done with it. 297. """ 298. 299. if dir is None: 300. dir = gettempdir() 301. 302. names = _get_candidate_names() 303. 304. for seq in xrange(TMP_MAX): 305. name = names.next() 306. file = _os.path.join(dir, prefix + name + suffix) 307. try: 308. _os.mkdir(file, 0700) 309. return file 310. except OSError, e: 311. if e.errno == _errno.EEXIST: 312. continue # try again 313. raise 314. 315. raise IOError, (_errno.EEXIST, "No usable temporary directory name found") 316. 317. def mktemp(suffix="", prefix=template, dir=None): 318. """mktemp([suffix, [prefix, [dir]]]) 319. User-callable function to return a unique temporary file name. The 320. file is not created. 321. 322. Arguments are as for mkstemp, except that the 'text' argument is 323. not accepted. 324. 325. This function is unsafe and should not be used. The file name 326. refers to a file that did not exist at some point, but by the time 327. you get around to creating it, someone else may have beaten you to 328. the punch. 329. """ 330. 331. ## from warnings import warn as _warn 332. ## _warn("mktemp is a potential security risk to your program", 333. ## RuntimeWarning, stacklevel=2) 334. 335. if dir is None: 336. dir = gettempdir() 337. 338. names = _get_candidate_names() 339. for seq in xrange(TMP_MAX): 340. name = names.next() 341. file = _os.path.join(dir, prefix + name + suffix) 342. if not _os.path.exists(file): 343. return file 344. 345. raise IOError, (_errno.EEXIST, "No usable temporary filename found") 346. 347. class _TemporaryFileWrapper: 348. """Temporary file wrapper 349. 350. This class provides a wrapper around files opened for 351. temporary use. In particular, it seeks to automatically 352. remove the file when it is no longer needed. 353. """ 354. 355. def __init__(self, file, name): 356. self.file = file 357. self.name = name 358. self.close_called = False 359. 360. def __getattr__(self, name): 361. file = self.__dict__['file'] 362. a = getattr(file, name) 363. if type(a) != type(0): 364. setattr(self, name, a) 365. return a 366. 367. # NT provides delete-on-close as a primitive, so we don't need 368. # the wrapper to do anything special. We still use it so that 369. # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. 370. if _os.name != 'nt': 371. 372. # Cache the unlinker so we don't get spurious errors at 373. # shutdown when the module-level "os" is None'd out. Note 374. # that this must be referenced as self.unlink, because the 375. # name TemporaryFileWrapper may also get None'd out before 376. # __del__ is called. 377. unlink = _os.unlink 378. 379. def close(self): 380. if not self.close_called: 381. self.close_called = True 382. self.file.close() 383. self.unlink(self.name) 384. 385. def __del__(self): 386. self.close() 387. 388. def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="", 389. prefix=template, dir=None): 390. """Create and return a temporary file. 391. Arguments: 392. 'prefix', 'suffix', 'dir' -- as for mkstemp. 393. 'mode' -- the mode argument to os.fdopen (default "w+b"). 394. 'bufsize' -- the buffer size argument to os.fdopen (default -1). 395. The file is created as mkstemp() would do it. 396. 397. Returns a file object; the name of the file is accessible as 398. file.name. The file will be automatically deleted when it is 399. closed. 400. """ 401. 402. if dir is None: 403. dir = gettempdir() 404. 405. if 'b' in mode: 406. flags = _bin_openflags 407. else: 408. flags = _text_openflags 409. 410. # Setting O_TEMPORARY in the flags causes the OS to delete 411. # the file when it is closed. This is only supported by Windows. 412. if _os.name == 'nt': 413. flags |= _os.O_TEMPORARY 414. 415. (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 416. file = _os.fdopen(fd, mode, bufsize) 417. return _TemporaryFileWrapper(file, name) 418. 419. if _os.name != 'posix' or _os.sys.platform == 'cygwin': 420. # On non-POSIX and Cygwin systems, assume that we cannot unlink a file 421. # while it is open. 422. TemporaryFile = NamedTemporaryFile 423. 424. else: 425. def TemporaryFile(mode='w+b', bufsize=-1, suffix="", 426. prefix=template, dir=None): 427. """Create and return a temporary file. 428. Arguments: 429. 'prefix', 'suffix', 'directory' -- as for mkstemp. 430. 'mode' -- the mode argument to os.fdopen (default "w+b"). 431. 'bufsize' -- the buffer size argument to os.fdopen (default -1). 432. The file is created as mkstemp() would do it. 433. 434. Returns a file object. The file has no name, and will cease to 435. exist when it is closed. 436. """ 437. 438. if dir is None: 439. dir = gettempdir() 440. 441. if 'b' in mode: 442. flags = _bin_openflags 443. else: 444. flags = _text_openflags 445. 446. (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) 447. try: 448. _os.unlink(name) 449. return _os.fdopen(fd, mode, bufsize) 450. except: 451. _os.close(fd) 452. raise