Patch: File.createTempFile

Tom Tromey tromey@cygnus.com
Fri Feb 11 09:31:00 GMT 2000


I'm committing the appended patch.
It adds a method I needed to java.io.File.

2000-02-10  Tom Tromey  <tromey@cygnus.com>

	* java/io/natFileDescriptorPosix.cc (open): Recognize EXCL flag.
	* java/io/FileDescriptor.java (EXCL): New static field.
	* java/io/File.java (tmpdir): New static field.
	(createTempFile): New method.
	(nextValue): New method.
	* java/lang/natSystem.cc (init_properties): Set java.io.tmpdir
	property.

Tom

Index: java/io/File.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/File.java,v
retrieving revision 1.4
diff -u -r1.4 File.java
--- File.java	2000/01/19 18:39:25	1.4
+++ File.java	2000/02/11 17:29:55
@@ -1,6 +1,6 @@
 // File.java - File name
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -215,6 +215,68 @@
     return mkdirs (new File (path));
   }
 
+  private static String nextValue ()
+  {
+    return Long.toString(counter++, Character.MAX_RADIX);
+  }
+
+  public static File createTempFile (String prefix, String suffix,
+				     File directory)
+    throws IOException
+  {
+    FileDescriptor desc = new FileDescriptor ();
+
+    SecurityManager s = System.getSecurityManager();
+    if (s != null)
+      s.checkWrite (desc);
+
+    if (prefix.length () < 3)
+      throw new IllegalArgumentException ();
+    if (suffix == null)
+      suffix = ".tmp";
+
+    // FIXME: filename length varies by architecture and filesystem.
+    int max_length = 255;
+
+    // Truncation rules.
+    // `6' is the number of characters we generate.
+    if (prefix.length () + 6 + suffix.length () > max_length)
+      {
+	int suf_len = 0;
+	if (suffix.charAt(0) == '.')
+	  suf_len = 4;
+	suffix = suffix.substring(0, suf_len);
+	if (prefix.length () + 6 + suf_len > max_length)
+	  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)
+      {
+	// This is ugly.
+	String l = prefix + (nextValue () + "ZZZZZZ").substring(0,6) + suffix;
+	try
+	  {
+	    desc.open (l, FileDescriptor.WRITE | FileDescriptor.EXCL);
+	    ret.setPath(l);
+	    return ret;
+	  }
+	catch (IOException _)
+	  {
+	  }
+      }
+
+    throw new IOException ("couldn't make temp file");
+  }
+
+  public static File createTempFile (String prefix, String suffix)
+    throws IOException
+  {
+    return createTempFile (prefix, suffix, null);
+  }
+
   private final native boolean performRenameTo (File dest);
   public boolean renameTo (File dest)
   {
@@ -234,9 +296,14 @@
   public static final String separator = System.getProperty("file.separator");
   public static final char separatorChar = separator.charAt(0);
 
+  private static final String tmpdir = System.getProperty("java.io.tmpdir");
 
   // The path.
   private String path;
+
+  // We keep a counter for use by createTempFile.  We choose the first
+  // value randomly to try to avoid clashes with other VMs.
+  private static long counter = Double.doubleToLongBits (Math.random ());
 
   // mkdirs() uses this to avoid repeated allocations.
   private final void setPath (String n)
Index: java/io/FileDescriptor.java
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/FileDescriptor.java,v
retrieving revision 1.3
diff -u -r1.3 FileDescriptor.java
--- FileDescriptor.java	2000/01/19 18:39:25	1.3
+++ FileDescriptor.java	2000/02/11 17:29:55
@@ -1,6 +1,6 @@
 // FileDescriptor.java - Open file or device
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -36,6 +36,8 @@
   static final int READ   = 1;
   static final int WRITE  = 2;
   static final int APPEND = 4;
+  // EXCL is used only when making a temp file.
+  static final int EXCL   = 8;
 
   // These are WHENCE values for seek.
   static final int SET = 0;
Index: java/io/natFileDescriptorPosix.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/io/natFileDescriptorPosix.cc,v
retrieving revision 1.5
diff -u -r1.5 natFileDescriptorPosix.cc
--- natFileDescriptorPosix.cc	2000/01/19 18:39:25	1.5
+++ natFileDescriptorPosix.cc	2000/02/11 17:29:58
@@ -1,6 +1,6 @@
 // natFileDescriptor.cc - Native part of FileDescriptor class.
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -83,6 +83,7 @@
 #endif
 
   JvAssert ((jflags & READ) || (jflags & WRITE));
+  int mode = 0644;
   if ((jflags & READ) && (jflags & WRITE))
     flags |= O_RDWR;
   else if ((jflags & READ))
@@ -94,9 +95,16 @@
 	flags |= O_APPEND;
       else
 	flags |= O_TRUNC;
+
+      if ((jflags & EXCL))
+	{
+	  flags |= O_EXCL;
+	  // In this case we are making a temp file.
+	  mode = 0600;
+	}
     }
 
-  int fd = ::open (buf, flags, 0644);
+  int fd = ::open (buf, flags, mode);
   if (fd == -1)
     {
       char msg[MAXPATHLEN + 200];
Index: java/lang/natSystem.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natSystem.cc,v
retrieving revision 1.17
diff -u -r1.17 natSystem.cc
--- natSystem.cc	2000/01/19 18:39:26	1.17
+++ natSystem.cc	2000/02/11 17:30:02
@@ -270,11 +270,14 @@
   SET ("file.separator", "\\");
   SET ("path.separator", ";");
   SET ("line.separator", "\r\n");
+  SET ("java.io.tmpdir", "C:\\temp");
 #else
   // Unix.
   SET ("file.separator", "/");
   SET ("path.separator", ":");
   SET ("line.separator", "\n");
+  // FIXME: look at getenv("TMPDIR");
+  SET ("java.io.tmpdir", "/tmp");
 #endif
 
 #ifdef HAVE_UNAME


More information about the Java-patches mailing list