Bug 482942. Implement nsILocalFile::DELETE_ON_CLOSE. r=bsmedberg
--- 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());
}