annotate Lib/tempfile.py @ 25838:8540887bcec6 2.2

Backport of 2.183: Fix memory leak in add_subclass() found by NealN with valgrind.
author Guido van Rossum <guido@python.org>
date Fri, 18 Oct 2002 13:42:21 +0000
parents 641fb4b4720e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11707
6f4146846337 The third and final doc-string sweep by Ka-Ping Yee.
Guido van Rossum <guido@python.org>
parents: 10901
diff changeset
1 """Temporary files and filenames."""
6f4146846337 The third and final doc-string sweep by Ka-Ping Yee.
Guido van Rossum <guido@python.org>
parents: 10901
diff changeset
2
773
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
3 # XXX This tries to be not UNIX specific, but I don't know beans about
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
4 # how to choose a temp directory or filename on MS-DOS or other
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
5 # systems so it may have to be changed...
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
6
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
7 import os
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
8
16889
0feb63490093 final round of __all__ lists (I hope) - skipped urllib2 because Moshe may be
Skip Montanaro <skip@pobox.com>
parents: 16678
diff changeset
9 __all__ = ["mktemp", "TemporaryFile", "tempdir", "gettempprefix"]
0feb63490093 final round of __all__ lists (I hope) - skipped urllib2 because Moshe may be
Skip Montanaro <skip@pobox.com>
parents: 16678
diff changeset
10
773
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
11 # Parameters that the caller may set to override the defaults
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
12 tempdir = None
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
13 template = None
430
0f9ebc63dcb5 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14
773
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
15 def gettempdir():
11707
6f4146846337 The third and final doc-string sweep by Ka-Ping Yee.
Guido van Rossum <guido@python.org>
parents: 10901
diff changeset
16 """Function to calculate the directory to use."""
3647
16ca8f0f3f11 Be more careful about default temp dir
Guido van Rossum <guido@python.org>
parents: 773
diff changeset
17 global tempdir
3954
9d8a965de7ec Restore 1.3 behavior of gettempdir(): if tempdir is already set, believe it.
Guido van Rossum <guido@python.org>
parents: 3647
diff changeset
18 if tempdir is not None:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
19 return tempdir
22342
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
20
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
21 # _gettempdir_inner deduces whether a candidate temp dir is usable by
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
22 # trying to create a file in it, and write to it. If that succeeds,
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
23 # great, it closes the file and unlinks it. There's a race, though:
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
24 # the *name* of the test file it tries is the same across all threads
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
25 # under most OSes (Linux is an exception), and letting multiple threads
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
26 # all try to open, write to, close, and unlink a single file can cause
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
27 # a variety of bogus errors (e.g., you cannot unlink a file under
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
28 # Windows if anyone has it open, and two threads cannot create the
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
29 # same file in O_EXCL mode under Unix). The simplest cure is to serialize
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
30 # calls to _gettempdir_inner. This isn't a real expense, because the
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
31 # first thread to succeed sets the global tempdir, and all subsequent
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
32 # calls to gettempdir() reuse that without trying _gettempdir_inner.
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
33 _tempdir_lock.acquire()
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
34 try:
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
35 return _gettempdir_inner()
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
36 finally:
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
37 _tempdir_lock.release()
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
38
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
39 def _gettempdir_inner():
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
40 """Function to calculate the directory to use."""
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
41 global tempdir
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
42 if tempdir is not None:
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
43 return tempdir
7927
1126e72e5ee9 When getcwd() doesn't exist or raises an exception, don't fail but
Guido van Rossum <guido@python.org>
parents: 7755
diff changeset
44 try:
1126e72e5ee9 When getcwd() doesn't exist or raises an exception, don't fail but
Guido van Rossum <guido@python.org>
parents: 7755
diff changeset
45 pwd = os.getcwd()
1126e72e5ee9 When getcwd() doesn't exist or raises an exception, don't fail but
Guido van Rossum <guido@python.org>
parents: 7755
diff changeset
46 except (AttributeError, os.error):
1126e72e5ee9 When getcwd() doesn't exist or raises an exception, don't fail but
Guido van Rossum <guido@python.org>
parents: 7755
diff changeset
47 pwd = os.curdir
16939
09aec668df3a Search /tmp before /var/tmp and /usr/tmp -- this seems preferred.
Guido van Rossum <guido@python.org>
parents: 16889
diff changeset
48 attempdirs = ['/tmp', '/var/tmp', '/usr/tmp', pwd]
4077
10c084942cf1 Attempt at Windows-NT compatibility.
Guido van Rossum <guido@python.org>
parents: 3954
diff changeset
49 if os.name == 'nt':
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
50 attempdirs.insert(0, 'C:\\TEMP')
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
51 attempdirs.insert(0, '\\TEMP')
5305
332fe02bf02d (Jack:) Better MacOS support.
Guido van Rossum <guido@python.org>
parents: 4077
diff changeset
52 elif os.name == 'mac':
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
53 import macfs, MACFS
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
54 try:
15873
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
55 refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk,
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
56 MACFS.kTemporaryFolderType, 1)
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
57 dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
58 attempdirs.insert(0, dirname)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
59 except macfs.error:
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
60 pass
20654
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 16939
diff changeset
61 elif os.name == 'riscos':
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 16939
diff changeset
62 scrapdir = os.getenv('Wimp$ScrapDir')
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 16939
diff changeset
63 if scrapdir:
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 16939
diff changeset
64 attempdirs.insert(0, scrapdir)
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
65 for envname in 'TMPDIR', 'TEMP', 'TMP':
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
66 if os.environ.has_key(envname):
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
67 attempdirs.insert(0, os.environ[envname])
4077
10c084942cf1 Attempt at Windows-NT compatibility.
Guido van Rossum <guido@python.org>
parents: 3954
diff changeset
68 testfile = gettempprefix() + 'test'
3647
16ca8f0f3f11 Be more careful about default temp dir
Guido van Rossum <guido@python.org>
parents: 773
diff changeset
69 for dir in attempdirs:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
70 try:
15873
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
71 filename = os.path.join(dir, testfile)
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
72 if os.name == 'posix':
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
73 try:
16678
06ad5053f40a fix long line
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 15873
diff changeset
74 fd = os.open(filename,
06ad5053f40a fix long line
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 15873
diff changeset
75 os.O_RDWR | os.O_CREAT | os.O_EXCL, 0700)
15873
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
76 except OSError:
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
77 pass
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
78 else:
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
79 fp = os.fdopen(fd, 'w')
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
80 fp.write('blat')
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
81 fp.close()
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
82 os.unlink(filename)
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
83 del fp, fd
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
84 tempdir = dir
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
85 break
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
86 else:
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
87 fp = open(filename, 'w')
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
88 fp.write('blat')
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
89 fp.close()
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
90 os.unlink(filename)
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
91 tempdir = dir
3dd217fbdd59 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 15852
diff changeset
92 break
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
93 except IOError:
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
94 pass
3647
16ca8f0f3f11 Be more careful about default temp dir
Guido van Rossum <guido@python.org>
parents: 773
diff changeset
95 if tempdir is None:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
96 msg = "Can't find a usable temporary directory amongst " + `attempdirs`
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
97 raise IOError, msg
3647
16ca8f0f3f11 Be more careful about default temp dir
Guido van Rossum <guido@python.org>
parents: 773
diff changeset
98 return tempdir
586
dbf408918201 Use $TMPDIR if it is set in the environment.
Guido van Rossum <guido@python.org>
parents: 534
diff changeset
99
773
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
100
15840
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
101 # template caches the result of gettempprefix, for speed, when possible.
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
102 # XXX unclear why this isn't "_template"; left it "template" for backward
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
103 # compatibility.
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
104 if os.name == "posix":
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
105 # We don't try to cache the template on posix: the pid may change on us
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
106 # between calls due to a fork, and on Linux the pid changes even for
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
107 # another thread in the same process. Since any attempt to keep the
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
108 # cache in synch would have to call os.getpid() anyway in order to make
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
109 # sure the pid hasn't changed between calls, a cache wouldn't save any
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
110 # time. In addition, a cache is difficult to keep correct with the pid
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
111 # changing willy-nilly, and earlier attempts proved buggy (races).
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
112 template = None
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
113
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
114 # Else the pid never changes, so gettempprefix always returns the same
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
115 # string.
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
116 elif os.name == "nt":
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
117 template = '~' + `os.getpid()` + '-'
20654
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 16939
diff changeset
118 elif os.name in ('mac', 'riscos'):
15840
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
119 template = 'Python-Tmp-'
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
120 else:
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
121 template = 'tmp' # XXX might choose a better one
9364
9f135b3d9a78 Fix so that after a fork() -- on Unix only -- the template gets
Guido van Rossum <guido@python.org>
parents: 8176
diff changeset
122
773
c721afab0efa Mostly rewritten to be more flexible and more portable
Guido van Rossum <guido@python.org>
parents: 586
diff changeset
123 def gettempprefix():
15840
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
124 """Function to calculate a prefix of the filename to use.
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
125
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
126 This incorporates the current process id on systems that support such a
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
127 notion, so that concurrent processes don't generate the same prefix.
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
128 """
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
129
15852
0d8b5b3d9d83 Reverting a dumb experimental version I checked in by mistake.
Tim Peters <tim.peters@gmail.com>
parents: 15851
diff changeset
130 global template
9364
9f135b3d9a78 Fix so that after a fork() -- on Unix only -- the template gets
Guido van Rossum <guido@python.org>
parents: 8176
diff changeset
131 if template is None:
15852
0d8b5b3d9d83 Reverting a dumb experimental version I checked in by mistake.
Tim Peters <tim.peters@gmail.com>
parents: 15851
diff changeset
132 return '@' + `os.getpid()` + '.'
15840
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
133 else:
7d5025bba037 Guido found a brand new race in tempfile on Linux, due to Linux changing
Tim Peters <tim.peters@gmail.com>
parents: 15827
diff changeset
134 return template
586
dbf408918201 Use $TMPDIR if it is set in the environment.
Guido van Rossum <guido@python.org>
parents: 534
diff changeset
135
430
0f9ebc63dcb5 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
136
6924
cf317a9c499b Add new optional parameter 'suffix' (default ''), which is appended to
Guido van Rossum <guido@python.org>
parents: 6857
diff changeset
137 def mktemp(suffix=""):
11707
6f4146846337 The third and final doc-string sweep by Ka-Ping Yee.
Guido van Rossum <guido@python.org>
parents: 10901
diff changeset
138 """User-callable function to return a unique temporary file name."""
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
139 dir = gettempdir()
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
140 pre = gettempprefix()
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
141 while 1:
15827
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
142 i = _counter.get_next()
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
143 file = os.path.join(dir, pre + str(i) + suffix)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
144 if not os.path.exists(file):
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
145 return file
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
146
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
147
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
148 class TemporaryFileWrapper:
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
149 """Temporary file wrapper
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
150
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
151 This class provides a wrapper around files opened for temporary use.
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
152 In particular, it seeks to automatically remove the file when it is
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
153 no longer needed.
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
154 """
21474
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
155
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
156 # Cache the unlinker so we don't get spurious errors at shutdown
21476
af2623bb5d0b TemporaryFileWrapper: fixed typo in new comment.
Tim Peters <tim.peters@gmail.com>
parents: 21474
diff changeset
157 # when the module-level "os" is None'd out. Note that this must
21474
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
158 # be referenced as self.unlink, because the name TemporaryFileWrapper
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
159 # may also get None'd out before __del__ is called.
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
160 unlink = os.unlink
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
161
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
162 def __init__(self, file, path):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
163 self.file = file
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
164 self.path = path
20752
f2af42cf827a SF bug #476138: tempfile behavior across platforms
Tim Peters <tim.peters@gmail.com>
parents: 20654
diff changeset
165 self.close_called = 0
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
166
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
167 def close(self):
20752
f2af42cf827a SF bug #476138: tempfile behavior across platforms
Tim Peters <tim.peters@gmail.com>
parents: 20654
diff changeset
168 if not self.close_called:
f2af42cf827a SF bug #476138: tempfile behavior across platforms
Tim Peters <tim.peters@gmail.com>
parents: 20654
diff changeset
169 self.close_called = 1
f2af42cf827a SF bug #476138: tempfile behavior across platforms
Tim Peters <tim.peters@gmail.com>
parents: 20654
diff changeset
170 self.file.close()
21474
a3b0673ba2ca TemporaryFileWrapper: cache the value of os.unlink for use by __del__,
Tim Peters <tim.peters@gmail.com>
parents: 20752
diff changeset
171 self.unlink(self.path)
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
172
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
173 def __del__(self):
20752
f2af42cf827a SF bug #476138: tempfile behavior across platforms
Tim Peters <tim.peters@gmail.com>
parents: 20654
diff changeset
174 self.close()
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
175
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
176 def __getattr__(self, name):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
177 file = self.__dict__['file']
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
178 a = getattr(file, name)
10901
17ca2f64b6d6 In class TemporaryFileWrapper, don't cache attributes of tpye int --
Guido van Rossum <guido@python.org>
parents: 9447
diff changeset
179 if type(a) != type(0):
17ca2f64b6d6 In class TemporaryFileWrapper, don't cache attributes of tpye int --
Guido van Rossum <guido@python.org>
parents: 9447
diff changeset
180 setattr(self, name, a)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
181 return a
5987
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
182
0a2c331200f5 Added TemporaryFile and wrapper class by Jim Fulton.
Guido van Rossum <guido@python.org>
parents: 5305
diff changeset
183
6924
cf317a9c499b Add new optional parameter 'suffix' (default ''), which is appended to
Guido van Rossum <guido@python.org>
parents: 6857
diff changeset
184 def TemporaryFile(mode='w+b', bufsize=-1, suffix=""):
11707
6f4146846337 The third and final doc-string sweep by Ka-Ping Yee.
Guido van Rossum <guido@python.org>
parents: 10901
diff changeset
185 """Create and return a temporary file (opened read-write by default)."""
6924
cf317a9c499b Add new optional parameter 'suffix' (default ''), which is appended to
Guido van Rossum <guido@python.org>
parents: 6857
diff changeset
186 name = mktemp(suffix)
9443
56217eabc07a The TemporaryFile() function has a security leak -- because the
Guido van Rossum <guido@python.org>
parents: 9364
diff changeset
187 if os.name == 'posix':
56217eabc07a The TemporaryFile() function has a security leak -- because the
Guido van Rossum <guido@python.org>
parents: 9364
diff changeset
188 # Unix -- be very careful
56217eabc07a The TemporaryFile() function has a security leak -- because the
Guido van Rossum <guido@python.org>
parents: 9364
diff changeset
189 fd = os.open(name, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700)
9447
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
190 try:
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
191 os.unlink(name)
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
192 return os.fdopen(fd, mode, bufsize)
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
193 except:
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
194 os.close(fd)
25b6929ffb13 Improvement to the previous fix suggested by Thomas Bellman: if the
Guido van Rossum <guido@python.org>
parents: 9443
diff changeset
195 raise
9443
56217eabc07a The TemporaryFile() function has a security leak -- because the
Guido van Rossum <guido@python.org>
parents: 9364
diff changeset
196 else:
22343
641fb4b4720e Stop using not-exposed-in-22x os.O_ constants.
Michael W. Hudson <mwh@python.net>
parents: 22342
diff changeset
197 # Non-unix -- can't unlink file that's still open, use wrapper
9443
56217eabc07a The TemporaryFile() function has a security leak -- because the
Guido van Rossum <guido@python.org>
parents: 9364
diff changeset
198 file = open(name, mode, bufsize)
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 6924
diff changeset
199 return TemporaryFileWrapper(file, name)
15827
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
200
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
201 # In order to generate unique names, mktemp() uses _counter.get_next().
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
202 # This returns a unique integer on each call, in a threadsafe way (i.e.,
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
203 # multiple threads will never see the same integer). The integer will
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
204 # usually be a Python int, but if _counter.get_next() is called often
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
205 # enough, it will become a Python long.
22342
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
206 # Note that the only names that survive this next block of code
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
207 # are "_counter" and "_tempdir_lock".
15827
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
208
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
209 class _ThreadSafeCounter:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
210 def __init__(self, mutex, initialvalue=0):
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
211 self.mutex = mutex
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
212 self.i = initialvalue
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
213
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
214 def get_next(self):
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
215 self.mutex.acquire()
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
216 result = self.i
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
217 try:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
218 newi = result + 1
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
219 except OverflowError:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
220 newi = long(result) + 1
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
221 self.i = newi
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
222 self.mutex.release()
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
223 return result
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
224
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
225 try:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
226 import thread
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
227
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
228 except ImportError:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
229 class _DummyMutex:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
230 def acquire(self):
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
231 pass
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
232
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
233 release = acquire
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
234
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
235 _counter = _ThreadSafeCounter(_DummyMutex())
22342
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
236 _tempdir_lock = _DummyMutex()
15827
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
237 del _DummyMutex
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
238
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
239 else:
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
240 _counter = _ThreadSafeCounter(thread.allocate_lock())
22342
12d204d93af3 So there is some merit in slogging through ~4800 lines of cvs log.
Michael W. Hudson <mwh@python.net>
parents: 21476
diff changeset
241 _tempdir_lock = thread.allocate_lock()
15827
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
242 del thread
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
243
81db92e80ea8 A variant of SF patch 103028 (Make tempfile.mktemp threadsafe).
Tim Peters <tim.peters@gmail.com>
parents: 14242
diff changeset
244 del _ThreadSafeCounter