Bug 482942. Implement nsILocalFile::DELETE_ON_CLOSE. r=bsmedberg
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 20 Mar 2009 09:56:05 +1300
changeset 26480 1517b7567b2895c007f1401a82fb1959114ab7d4
parent 26479 1c35af83002a1f1cf24f67671771b7ac3cf4bbd6
child 26481 dea4ff139073f8b643438e3a3f0be679e956011e
push id6097
push userrocallahan@mozilla.com
push dateTue, 24 Mar 2009 00:59:28 +0000
treeherdermozilla-central@60da3e72b4cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs482942
milestone1.9.2a1pre
Bug 482942. Implement nsILocalFile::DELETE_ON_CLOSE. r=bsmedberg
xpcom/io/nsILocalFile.idl
xpcom/io/nsLocalFileOS2.cpp
xpcom/io/nsLocalFileOSX.mm
xpcom/io/nsLocalFileUnix.cpp
xpcom/io/nsLocalFileWin.cpp
--- a/xpcom/io/nsILocalFile.idl
+++ b/xpcom/io/nsILocalFile.idl
@@ -96,19 +96,27 @@ interface nsILocalFile : nsIFile
      *
      *  This attribute will determine if the nsLocalFile will auto
      *  resolve symbolic links.  By default, this value will be false
      *  on all non unix systems.  On unix, this attribute is effectively
      *  a noop.  
      */
     attribute PRBool followLinks;  
 
+    const unsigned long DELETE_ON_CLOSE = 0x80000000;
+
     /**
      * Return the result of PR_Open on the file.  The caller is
      * responsible for calling PR_Close on the result.
+     *
+     * @param flags the PR_Open flags from prio.h, plus optionally
+     * DELETE_ON_CLOSE. DELETE_ON_CLOSE may be implemented by removing
+     * the file (by path name) immediately after opening it, so beware
+     * of possible races; the file should be exclusively owned by this
+     * process.
      */
     [noscript] PRFileDescStar openNSPRFileDesc(in long flags, in long mode);
 
     /**
      * Return the result of fopen on the file.  The caller is
      * responsible for calling fclose on the result.
      */
     [noscript] FILE           openANSIFileDesc(in string mode);
--- a/xpcom/io/nsLocalFileOS2.cpp
+++ b/xpcom/io/nsLocalFileOS2.cpp
@@ -726,16 +726,20 @@ nsLocalFile::OpenNSPRFileDesc(PRInt32 fl
     nsresult rv = Stat();
     if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
         return rv;
 
     *_retval = PR_Open(mWorkingPath.get(), flags, mode);
     if (*_retval)
         return NS_OK;
 
+    if (flags & DELETE_ON_CLOSE) {
+        PR_Delete(mWorkingPath.get());
+    }
+
     return NS_ErrorAccordingToNSPR();
 }
 
 
 NS_IMETHODIMP
 nsLocalFile::OpenANSIFileDesc(const char *mode, FILE * *_retval)
 {
     nsresult rv = Stat();
@@ -744,18 +748,16 @@ nsLocalFile::OpenANSIFileDesc(const char
 
     *_retval = fopen(mWorkingPath.get(), mode);
     if (*_retval)
         return NS_OK;
 
     return NS_ERROR_FAILURE;
 }
 
-
-
 NS_IMETHODIMP
 nsLocalFile::Create(PRUint32 type, PRUint32 attributes)
 {
     if (type != NORMAL_FILE_TYPE && type != DIRECTORY_TYPE)
         return NS_ERROR_FILE_UNKNOWN_TYPE;
 
     nsresult rv = Stat();
     if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)
--- a/xpcom/io/nsLocalFileOSX.mm
+++ b/xpcom/io/nsLocalFileOSX.mm
@@ -1462,16 +1462,20 @@ NS_IMETHODIMP nsLocalFile::OpenNSPRFileD
   nsresult rv = GetPathInternal(path);
   if (NS_FAILED(rv))
     return rv;
     
   *_retval = PR_Open(path.get(), flags, mode);
   if (! *_retval)
     return NS_ErrorAccordingToNSPR();
 
+  if (flags & DELETE_ON_CLOSE) {
+    PR_Delete(path.get());
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP nsLocalFile::OpenANSIFileDesc(const char *mode, FILE **_retval)
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   nsCAutoString path;
--- a/xpcom/io/nsLocalFileUnix.cpp
+++ b/xpcom/io/nsLocalFileUnix.cpp
@@ -403,16 +403,20 @@ nsLocalFile::CreateAllAncestors(PRUint32
 
 NS_IMETHODIMP
 nsLocalFile::OpenNSPRFileDesc(PRInt32 flags, PRInt32 mode, PRFileDesc **_retval)
 {
     *_retval = PR_Open(mPath.get(), flags, mode);
     if (! *_retval)
         return NS_ErrorAccordingToNSPR();
 
+    if (flags & DELETE_ON_CLOSE) {
+        PR_Delete(mPath.get());
+    }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsLocalFile::OpenANSIFileDesc(const char *mode, FILE **_retval)
 {
     *_retval = fopen(mPath.get(), mode);
     if (! *_retval)
--- a/xpcom/io/nsLocalFileWin.cpp
+++ b/xpcom/io/nsLocalFileWin.cpp
@@ -396,16 +396,20 @@ OpenFile(const nsAFlatString &name, PRIn
             flags = OPEN_ALWAYS;
     } else {
         if (osflags & PR_TRUNCATE)
             flags = TRUNCATE_EXISTING;
         else
             flags = OPEN_EXISTING;
     }
 
+    if (osflags & nsILocalFile::DELETE_ON_CLOSE) {
+      flag6 |= FILE_FLAG_DELETE_ON_CLOSE;
+    }
+
     HANDLE file = ::CreateFileW(name.get(), access,
                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
                                 NULL, flags, flag6, NULL);
 
     if (file == INVALID_HANDLE_VALUE) { 
         *fd = nsnull;
         return ConvertWinError(GetLastError());
     }