[Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.35,1.36

Tim Peters tim_one@users.sourceforge.net
Tue, 29 Jan 2002 23:47:53 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv26448

Modified Files:
	tempfile.py 
Log Message:
New TemporaryFile implementation for Windows:  this doesn't need a
TemproraryFileWrapper wrapper anymore, and should be immune from the
problem that a temp file inherited by a spawned process caused an
attempt to close the temp file in the spawning process to blow
up (the unlink in TemporaryFileWrapper.close() blew up with a
"Permission denied" error because, despite that the temp file got
closed in the spawning process, the spawned process still had it open
by virtue of C-level file descriptor inheritance).  In context,
that bug took days to figure out <wink/sigh>.


Index: tempfile.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** tempfile.py	2002/01/28 23:11:23	1.35
--- tempfile.py	2002/01/30 07:47:51	1.36
***************
*** 194,199 ****
              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)
--- 194,215 ----
              os.close(fd)
              raise
+     elif os.name == 'nt':
+         # Windows -- can't unlink an open file, but O_TEMPORARY creates a
+         # file that "deletes itself" when the last handle is closed.
+         # O_NOINHERIT ensures processes created via spawn() don't get a
+         # handle to this too.  That would be a security hole, and, on my
+         # Win98SE box, when an O_TEMPORARY file is inherited by a spawned
+         # process, the fd in the spawned process seems to lack the
+         # O_TEMPORARY flag, so the file doesn't go away by magic then if the
+         # spawning process closes it first.
+         flags = (os.O_RDWR | os.O_CREAT | os.O_EXCL |
+                  os.O_TEMPORARY | os.O_NOINHERIT)
+         if 'b' in mode:
+             flags |= os.O_BINARY
+         fd = os.open(name, flags, 0700)
+         return os.fdopen(fd, mode, bufsize)
      else:
!         # Assume we can't unlink a file that's still open, or arrange for
!         # an automagically self-deleting file -- use wrapper.
          file = open(name, mode, bufsize)
          return TemporaryFileWrapper(file, name)