This is the mail archive of the
java-patches@sources.redhat.com
mailing list for the Java project.
Patch: File.createTempFile fixes
- To: java-patches at sources dot redhat dot com
- Subject: Patch: File.createTempFile fixes
- From: Anthony Green <green at cygnus dot com>
- Date: Mon, 4 Sep 2000 13:11:02 -0700
- Reply-to: green at cygnus dot com
This patch sets the java.io.tmpdir property based on the TMPDIR
environment variable.
It also revamps temp file creation to obey the specified directory and
close the FileDescriptor once created. Parts of it come from GNU
Classpath.
The 1.3 docs says that createTempFile throws an exception if "a
security manager exists and its
SecurityManager.checkWrite(java.io.FileDescriptor) method does not
allow a file to be created". I'm confused. Doesn't the fact that we
have a FileDescriptor mean the file has been created already? I
decided to split up the test for existance and file creation. I used
SecurityManager.checkWrite(String) in the middle. Comments?
2000-09-04 Anthony Green <green@redhat.com>
Fix for PR java.io/203:
* java/io/File.java (createTempFile): Obey directory argument.
Use java.io.tmpdir if needed. Don't leave FileDescripators open.
* java/lang/natSystem.cc (init_properties): Use TMPDIR environment
variable to set java.io.tmpdir on non-WIN32 systems.
Index: java/lang/natSystem.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natSystem.cc,v
retrieving revision 1.24
diff -u -p -u -r1.24 natSystem.cc
--- natSystem.cc 2000/08/26 19:25:13 1.24
+++ natSystem.cc 2000/09/04 19:47:10
@@ -244,8 +244,10 @@ java::lang::System::init_properties (voi
SET ("file.separator", "/");
SET ("path.separator", ":");
SET ("line.separator", "\n");
- // FIXME: look at getenv("TMPDIR");
- SET ("java.io.tmpdir", "/tmp");
+ char *tmpdir = ::getenv("TMPDIR");
+ if (! tmpdir)
+ tmpdir = "/tmp";
+ SET ("java.io.tmpdir", tmpdir);
#endif
#ifdef HAVE_UNAME
Index: java/io/File.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/File.java,v
retrieving revision 1.12
diff -u -p -u -r1.12 File.java
--- File.java 2000/09/04 16:55:47 1.12
+++ File.java 2000/09/04 19:47:10
@@ -233,14 +233,26 @@ public class File implements Serializabl
File directory)
throws IOException
{
- FileDescriptor desc = new FileDescriptor ();
-
- SecurityManager s = System.getSecurityManager();
- if (s != null)
- s.checkWrite (desc);
+ // Grab the system temp directory if necessary
+ if (directory == null)
+ {
+ String dirname = tmpdir;
+ if (dirname == null)
+ throw
+ new IOException("Cannot determine system temporary directory");
+
+ directory = new File(dirname);
+ if (!directory.exists())
+ throw new IOException("System temporary directory "
+ + directory.getName() + " does not exist.");
+ if (!directory.isDirectory())
+ throw new IOException("System temporary directory "
+ + directory.getName()
+ + " is not really a directory.");
+ }
if (prefix.length () < 3)
- throw new IllegalArgumentException ();
+ throw new IllegalArgumentException ("Prefix too short: " + prefix);
if (suffix == null)
suffix = ".tmp";
@@ -259,28 +271,50 @@ public class File implements Serializabl
prefix = prefix.substring(0, max_length - 6 - suf_len);
}
- // We don't care about the name because we set it later.
- File ret = new File ("");
- // How many times should we try? We choose 100.
- for (int i = 0; i < 100; ++i)
+ File f;
+
+ // Synchronize because there's a race condition between checking
+ // for file existence and creating the temporary file.
+ // Synchronize on tmpdir because it is unique and convenient.
+ synchronized (tmpdir)
{
- // This is ugly.
- String t = "ZZZZZZ" + nextValue ();
- String l = prefix + t.substring(t.length() - 6) + suffix;
- try
- {
- desc = new FileDescriptor
- (l, FileDescriptor.WRITE | FileDescriptor.EXCL);
- desc.close ();
- ret.setPath(l);
- return ret;
- }
- catch (IOException _)
+ // How many times should we try? We choose 100.
+ for (int i = 0; i < 100; ++i)
{
+ // This is ugly.
+ String t = "ZZZZZZ" + nextValue ();
+ String l = prefix + t.substring(t.length() - 6) + suffix;
+ try
+ {
+ f = new File(directory, l);
+ if (f.exists())
+ continue;
+ else
+ {
+ String af = f.getAbsolutePath ();
+
+ // The file does not exist now. Check to see if
+ // we're allowed to write to it.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkWrite (af);
+
+ // Now create the file.
+ FileDescriptor fd =
+ new FileDescriptor (af,
+ FileDescriptor.WRITE
+ | FileDescriptor.EXCL);
+ fd.close ();
+ return f;
+ }
+ }
+ catch (IOException _)
+ {
+ }
}
}
- throw new IOException ("couldn't make temp file");
+ throw new IOException ("cannot create temporary file");
}
public static File createTempFile (String prefix, String suffix)
AG
--
Anthony Green Red Hat
Sunnyvale, California