diff options
Diffstat (limited to 'Mailman/pythonlib')
| -rw-r--r-- | Mailman/pythonlib/tempfile.py | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/Mailman/pythonlib/tempfile.py b/Mailman/pythonlib/tempfile.py new file mode 100644 index 000000000..1f301262d --- /dev/null +++ b/Mailman/pythonlib/tempfile.py @@ -0,0 +1,141 @@ +# Temporary file name allocation +# +# XXX This tries to be not UNIX specific, but I don't know beans about +# how to choose a temp directory or filename on MS-DOS or other +# systems so it may have to be changed... + + +import os + + +# Parameters that the caller may set to override the defaults + +tempdir = None +template = None + + +# Function to calculate the directory to use + +def gettempdir(): + global tempdir + if tempdir is not None: + return tempdir + try: + pwd = os.getcwd() + except (AttributeError, os.error): + pwd = os.curdir + attempdirs = ['/usr/tmp', '/tmp', pwd] + if os.name == 'nt': + attempdirs.insert(0, 'C:\\TEMP') + attempdirs.insert(0, '\\TEMP') + elif os.name == 'mac': + import macfs, MACFS + try: + refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, + MACFS.kTemporaryFolderType, 1) + dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname() + attempdirs.insert(0, dirname) + except macfs.error: + pass + for envname in 'TMPDIR', 'TEMP', 'TMP': + if os.environ.has_key(envname): + attempdirs.insert(0, os.environ[envname]) + testfile = gettempprefix() + 'test' + for dir in attempdirs: + try: + filename = os.path.join(dir, testfile) + fp = open(filename, 'w') + fp.write('blat') + fp.close() + os.unlink(filename) + tempdir = dir + break + except IOError: + pass + if tempdir is None: + msg = "Can't find a usable temporary directory amongst " + `attempdirs` + raise IOError, msg + return tempdir + + +# Function to calculate a prefix of the filename to use + +_pid = None + +def gettempprefix(): + global template, _pid + if os.name == 'posix' and _pid and _pid != os.getpid(): + # Our pid changed; we must have forked -- zap the template + template = None + if template is None: + if os.name == 'posix': + _pid = os.getpid() + template = '@' + `_pid` + '.' + elif os.name == 'nt': + template = '~' + `os.getpid()` + '-' + elif os.name == 'mac': + template = 'Python-Tmp-' + else: + template = 'tmp' # XXX might choose a better one + return template + + +# Counter for generating unique names + +counter = 0 + + +# User-callable function to return a unique temporary file name + +def mktemp(suffix=""): + global counter + dir = gettempdir() + pre = gettempprefix() + while 1: + counter = counter + 1 + file = os.path.join(dir, pre + `counter` + suffix) + if not os.path.exists(file): + return file + + +class TemporaryFileWrapper: + """Temporary file wrapper + + This class provides a wrapper around files opened for temporary use. + In particular, it seeks to automatically remove the file when it is + no longer needed. + """ + def __init__(self, file, path): + self.file = file + self.path = path + + def close(self): + self.file.close() + os.unlink(self.path) + + def __del__(self): + try: self.close() + except: pass + + def __getattr__(self, name): + file = self.__dict__['file'] + a = getattr(file, name) + setattr(self, name, a) + return a + + +def TemporaryFile(mode='w+b', bufsize=-1, suffix=""): + name = mktemp(suffix) + if os.name == 'posix': + # Unix -- be very careful + fd = os.open(name, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700) + try: + os.unlink(name) + return os.fdopen(fd, mode, bufsize) + except: + os.close(fd) + raise + else: + # Non-unix -- can't unlink file that's still open, use wrapper + file = open(name, mode, bufsize) + return TemporaryFileWrapper(file, name) |
