+ path += wxFILE_SEP_PATH;
+ }
+
+ path += name;
+
+#if defined(HAVE_MKSTEMP)
+ // scratch space for mkstemp()
+ path += wxT("XXXXXX");
+
+ // we need to copy the path to the buffer in which mkstemp() can modify it
+ wxCharBuffer buf(path.fn_str());
+
+ // cast is safe because the string length doesn't change
+ int fdTemp = mkstemp( (char*)(const char*) buf );
+ if ( fdTemp == -1 )
+ {
+ // this might be not necessary as mkstemp() on most systems should have
+ // already done it but it doesn't hurt neither...
+ path.clear();
+ }
+ else // mkstemp() succeeded
+ {
+ path = wxConvFile.cMB2WX( (const char*) buf );
+
+ #if wxUSE_FILE
+ // avoid leaking the fd
+ if ( fileTemp )
+ {
+ fileTemp->Attach(fdTemp);
+ }
+ else
+ #endif
+
+ #if wxUSE_FFILE
+ if ( ffileTemp )
+ {
+ #ifdef wx_fdopen
+ ffileTemp->Attach(wx_fdopen(fdTemp, "r+b"));
+ #else
+ ffileTemp->Open(path, wxT("r+b"));
+ close(fdTemp);
+ #endif
+ }
+ else
+ #endif
+
+ {
+ close(fdTemp);
+ }
+ }
+#else // !HAVE_MKSTEMP
+
+#ifdef HAVE_MKTEMP
+ // same as above
+ path += wxT("XXXXXX");
+
+ wxCharBuffer buf = wxConvFile.cWX2MB( path );
+ if ( !mktemp( (char*)(const char*) buf ) )
+ {
+ path.clear();
+ }
+ else
+ {
+ path = wxConvFile.cMB2WX( (const char*) buf );
+ }
+#else // !HAVE_MKTEMP (includes __DOS__)
+ // generate the unique file name ourselves
+ #if !defined(__DOS__) && !defined(__PALMOS__) && (!defined(__MWERKS__) || defined(__DARWIN__) )
+ path << (unsigned int)getpid();
+ #endif
+
+ wxString pathTry;
+
+ static const size_t numTries = 1000;
+ for ( size_t n = 0; n < numTries; n++ )
+ {
+ // 3 hex digits is enough for numTries == 1000 < 4096
+ pathTry = path + wxString::Format(wxT("%.03x"), (unsigned int) n);
+ if ( !wxFileName::FileExists(pathTry) )
+ {
+ break;
+ }
+
+ pathTry.clear();
+ }
+
+ path = pathTry;
+#endif // HAVE_MKTEMP/!HAVE_MKTEMP
+
+#endif // HAVE_MKSTEMP/!HAVE_MKSTEMP
+
+#endif // Windows/!Windows
+
+ if ( path.empty() )
+ {
+ wxLogSysError(_("Failed to create a temporary file name"));
+ }
+ else
+ {
+ bool ok = true;
+
+ // open the file - of course, there is a race condition here, this is
+ // why we always prefer using mkstemp()...
+ #if wxUSE_FILE
+ if ( fileTemp && !fileTemp->IsOpened() )
+ {
+ *deleteOnClose = wantDeleteOnClose;
+ int fd = wxTempOpen(path, deleteOnClose);
+ if (fd != -1)
+ fileTemp->Attach(fd);
+ else
+ ok = false;
+ }
+ #endif
+
+ #if wxUSE_FFILE
+ if ( ffileTemp && !ffileTemp->IsOpened() )
+ {
+ *deleteOnClose = wantDeleteOnClose;
+ ok = wxTempOpen(ffileTemp, path, deleteOnClose);
+ }
+ #endif
+
+ if ( !ok )
+ {
+ // FIXME: If !ok here should we loop and try again with another
+ // file name? That is the standard recourse if open(O_EXCL)
+ // fails, though of course it should be protected against
+ // possible infinite looping too.
+
+ wxLogError(_("Failed to open temporary file."));
+
+ path.clear();
+ }
+ }
+
+ return path;
+}
+
+
+static bool wxCreateTempImpl(
+ const wxString& prefix,
+ WXFILEARGS(wxFile *fileTemp, wxFFile *ffileTemp),
+ wxString *name)
+{
+ bool deleteOnClose = true;
+
+ *name = wxCreateTempImpl(prefix,
+ WXFILEARGS(fileTemp, ffileTemp),
+ &deleteOnClose);
+
+ bool ok = !name->empty();
+
+ if (deleteOnClose)
+ name->clear();
+#ifdef __UNIX__
+ else if (ok && wxRemoveFile(*name))
+ name->clear();
+#endif
+
+ return ok;
+}
+
+
+static void wxAssignTempImpl(
+ wxFileName *fn,
+ const wxString& prefix,
+ WXFILEARGS(wxFile *fileTemp, wxFFile *ffileTemp))
+{
+ wxString tempname;
+ tempname = wxCreateTempImpl(prefix, WXFILEARGS(fileTemp, ffileTemp));
+
+ if ( tempname.empty() )
+ {
+ // error, failed to get temp file name
+ fn->Clear();
+ }
+ else // ok
+ {
+ fn->Assign(tempname);
+ }
+}
+
+
+void wxFileName::AssignTempFileName(const wxString& prefix)
+{
+ wxAssignTempImpl(this, prefix, WXFILEARGS(NULL, NULL));
+}
+
+/* static */
+wxString wxFileName::CreateTempFileName(const wxString& prefix)
+{
+ return wxCreateTempImpl(prefix, WXFILEARGS(NULL, NULL));
+}
+
+#endif // wxUSE_FILE || wxUSE_FFILE
+
+
+#if wxUSE_FILE
+
+wxString wxCreateTempFileName(const wxString& prefix,
+ wxFile *fileTemp,
+ bool *deleteOnClose)
+{
+ return wxCreateTempImpl(prefix, WXFILEARGS(fileTemp, NULL), deleteOnClose);
+}
+
+bool wxCreateTempFile(const wxString& prefix,
+ wxFile *fileTemp,
+ wxString *name)
+{
+ return wxCreateTempImpl(prefix, WXFILEARGS(fileTemp, NULL), name);
+}
+
+void wxFileName::AssignTempFileName(const wxString& prefix, wxFile *fileTemp)
+{
+ wxAssignTempImpl(this, prefix, WXFILEARGS(fileTemp, NULL));
+}
+
+/* static */
+wxString
+wxFileName::CreateTempFileName(const wxString& prefix, wxFile *fileTemp)
+{
+ return wxCreateTempFileName(prefix, fileTemp);
+}
+
+#endif // wxUSE_FILE
+
+
+#if wxUSE_FFILE
+
+wxString wxCreateTempFileName(const wxString& prefix,
+ wxFFile *fileTemp,
+ bool *deleteOnClose)
+{
+ return wxCreateTempImpl(prefix, WXFILEARGS(NULL, fileTemp), deleteOnClose);
+}
+
+bool wxCreateTempFile(const wxString& prefix,
+ wxFFile *fileTemp,
+ wxString *name)
+{
+ return wxCreateTempImpl(prefix, WXFILEARGS(NULL, fileTemp), name);
+
+}
+
+void wxFileName::AssignTempFileName(const wxString& prefix, wxFFile *fileTemp)
+{
+ wxAssignTempImpl(this, prefix, WXFILEARGS(NULL, fileTemp));
+}
+
+/* static */
+wxString
+wxFileName::CreateTempFileName(const wxString& prefix, wxFFile *fileTemp)
+{
+ return wxCreateTempFileName(prefix, fileTemp);
+}
+
+#endif // wxUSE_FFILE
+
+
+// ----------------------------------------------------------------------------
+// directory operations
+// ----------------------------------------------------------------------------
+
+// helper of GetTempDir(): check if the given directory exists and return it if
+// it does or an empty string otherwise
+namespace
+{
+
+wxString CheckIfDirExists(const wxString& dir)
+{
+ return wxFileName::DirExists(dir) ? dir : wxString();
+}
+
+} // anonymous namespace
+
+wxString wxFileName::GetTempDir()
+{
+ // first try getting it from environment: this allows overriding the values
+ // used by default if the user wants to create temporary files in another
+ // directory
+ wxString dir = CheckIfDirExists(wxGetenv("TMPDIR"));
+ if ( dir.empty() )
+ {
+ dir = CheckIfDirExists(wxGetenv("TMP"));
+ if ( dir.empty() )
+ dir = CheckIfDirExists(wxGetenv("TEMP"));
+ }
+
+ // if no environment variables are set, use the system default
+ if ( dir.empty() )
+ {
+#if defined(__WXWINCE__)
+ dir = CheckIfDirExists(wxT("\\temp"));
+#elif defined(__WINDOWS__) && !defined(__WXMICROWIN__)
+ if ( !::GetTempPath(MAX_PATH, wxStringBuffer(dir, MAX_PATH + 1)) )
+ {
+ wxLogLastError(wxT("GetTempPath"));
+ }
+#elif defined(__WXMAC__) && wxOSX_USE_CARBON
+ dir = wxMacFindFolder(short(kOnSystemDisk), kTemporaryFolderType, kCreateFolder);
+#endif // systems with native way
+ }
+
+ // fall back to hard coded value
+ if ( dir.empty() )
+ {
+#ifdef __UNIX_LIKE__
+ dir = CheckIfDirExists("/tmp");
+ if ( dir.empty() )
+#endif // __UNIX_LIKE__
+ dir = ".";
+ }
+
+ return dir;
+}
+
+bool wxFileName::Mkdir( int perm, int flags ) const
+{
+ return wxFileName::Mkdir(GetPath(), perm, flags);
+}
+
+bool wxFileName::Mkdir( const wxString& dir, int perm, int flags )
+{
+ if ( flags & wxPATH_MKDIR_FULL )
+ {
+ // split the path in components
+ wxFileName filename;
+ filename.AssignDir(dir);
+
+ wxString currPath;
+ if ( filename.HasVolume())
+ {
+ currPath << wxGetVolumeString(filename.GetVolume(), wxPATH_NATIVE);
+ }
+
+ wxArrayString dirs = filename.GetDirs();