blob: d36898b3086de183d529d82e98a32fd9b6d5aa50 [file] [log] [blame]
Guido van Rossumeee94981991-11-12 15:38:08 +00001# Temporary file name allocation
Guido van Rossum41f95031992-03-31 19:02:01 +00002#
3# XXX This tries to be not UNIX specific, but I don't know beans about
4# how to choose a temp directory or filename on MS-DOS or other
5# systems so it may have to be changed...
Guido van Rossumeee94981991-11-12 15:38:08 +00006
7
Guido van Rossum41f95031992-03-31 19:02:01 +00008import os
Guido van Rossumeee94981991-11-12 15:38:08 +00009
Guido van Rossumeee94981991-11-12 15:38:08 +000010
Guido van Rossum41f95031992-03-31 19:02:01 +000011# Parameters that the caller may set to override the defaults
Guido van Rossumcff34541992-01-14 18:31:56 +000012
Guido van Rossum41f95031992-03-31 19:02:01 +000013tempdir = None
14template = None
15
16
17# Function to calculate the directory to use
18
19def gettempdir():
Guido van Rossumf4aaf861996-05-28 23:31:34 +000020 global tempdir
Guido van Rossum4033ad71996-08-08 18:33:56 +000021 if tempdir is not None:
22 return tempdir
Guido van Rossumf4aaf861996-05-28 23:31:34 +000023 attempdirs = ['/usr/tmp', '/tmp', os.getcwd(), os.curdir]
Guido van Rossum3e065ad1996-08-20 20:38:59 +000024 if os.name == 'nt':
25 attempdirs.insert(0, 'C:\\TEMP')
26 attempdirs.insert(0, '\\TEMP')
Guido van Rossumf4f756c1997-04-11 19:00:53 +000027 elif os.name == 'mac':
28 import macfs, MACFS
29 try:
30 refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, MACFS.kTemporaryFolderType, 0)
31 dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
32 attempdirs.insert(0, dirname)
33 except macfs.error:
34 pass
Guido van Rossumca549821997-08-12 18:00:12 +000035 for envname in 'TMPDIR', 'TEMP', 'TMP':
36 if os.environ.has_key(envname):
37 attempdirs.insert(0, os.environ[envname])
Guido van Rossum3e065ad1996-08-20 20:38:59 +000038 testfile = gettempprefix() + 'test'
Guido van Rossumf4aaf861996-05-28 23:31:34 +000039 for dir in attempdirs:
40 try:
41 filename = os.path.join(dir, testfile)
42 fp = open(filename, 'w')
43 fp.write('blat')
44 fp.close()
45 os.unlink(filename)
46 tempdir = dir
47 break
48 except IOError:
49 pass
50 if tempdir is None:
51 msg = "Can't find a usable temporary directory amongst " + `attempdirs`
52 raise IOError, msg
53 return tempdir
Guido van Rossum41f95031992-03-31 19:02:01 +000054
55
56# Function to calculate a prefix of the filename to use
57
58def gettempprefix():
59 global template
60 if template == None:
61 if os.name == 'posix':
62 template = '@' + `os.getpid()` + '.'
Guido van Rossum80fb3441997-12-15 19:11:53 +000063 elif os.name == 'nt':
64 template = '~' + `os.getpid()` + '-'
Guido van Rossumf4f756c1997-04-11 19:00:53 +000065 elif os.name == 'mac':
66 template = 'Python-Tmp-'
Guido van Rossum41f95031992-03-31 19:02:01 +000067 else:
68 template = 'tmp' # XXX might choose a better one
69 return template
Guido van Rossumcff34541992-01-14 18:31:56 +000070
Guido van Rossumeee94981991-11-12 15:38:08 +000071
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000072# Counter for generating unique names
Guido van Rossumeee94981991-11-12 15:38:08 +000073
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000074counter = 0
Guido van Rossumeee94981991-11-12 15:38:08 +000075
76
Guido van Rossum41f95031992-03-31 19:02:01 +000077# User-callable function to return a unique temporary file name
Guido van Rossumeee94981991-11-12 15:38:08 +000078
79def mktemp():
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000080 global counter
Guido van Rossum41f95031992-03-31 19:02:01 +000081 dir = gettempdir()
82 pre = gettempprefix()
Guido van Rossumeee94981991-11-12 15:38:08 +000083 while 1:
Guido van Rossum41f95031992-03-31 19:02:01 +000084 counter = counter + 1
85 file = os.path.join(dir, pre + `counter`)
86 if not os.path.exists(file):
87 return file
Guido van Rossumca549821997-08-12 18:00:12 +000088
89
90class TemporaryFileWrapper:
91 """Temporary file wrapper
92
93 This class provides a wrapper around files opened for temporary use.
94 In particular, it seeks to automatically remove the file when it is
95 no longer needed.
96 """
97 def __init__(self, file, path):
98 self.file=file
99 self.path=path
100
101 def close(self):
102 self.file.close()
103 os.unlink(self.path)
104
105 def __del__(self):
106 try: self.close()
107 except: pass
108
109 def __getattr__(self, name):
110 file=self.__dict__['file']
111 a=getattr(file, name)
112 setattr(self, name, a)
113 return a
114
115
116def TemporaryFile(mode='w+b', bufsize=-1):
117 name=mktemp()
118 file=open(name,mode,bufsize)
119 try:
120 os.unlink(name)
121 except os.error:
122 # Non-unix -- can't unlink file that's still open, use wrapper
123 return TemporaryFileWrapper(file, name)
124 else:
125 return file