file_util minor cleanup:
* add POSIX version of IsPathWritable
* convert IsPathWritable to FilePath
* convert CreateNewTempDirectory to FilePath
* fix a bug where recursive delete errors weren't being handled in POSIX
Review URL: http://codereview.chromium.org/16241

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7430 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: 7e1fde6a79fbc323f22a132dba6777dcd3464218
diff --git a/base/file_util.cc b/base/file_util.cc
index 1cf22b7..fe33c32 100644
--- a/base/file_util.cc
+++ b/base/file_util.cc
@@ -335,6 +335,19 @@
 bool CreateDirectory(const std::wstring& full_path) {
   return CreateDirectory(FilePath::FromWStringHack(full_path));
 }
+bool CreateNewTempDirectory(const std::wstring& prefix,
+                            std::wstring* new_temp_path) {
+#if defined(OS_WIN)
+  FilePath::StringType dir_prefix(prefix);
+#elif defined(OS_POSIX)
+  FilePath::StringType dir_prefix = WideToUTF8(prefix);
+#endif
+  FilePath temp_path;
+  if (!CreateNewTempDirectory(dir_prefix, &temp_path))
+    return false;
+  *new_temp_path = temp_path.ToWStringHack();
+  return true;
+}
 bool CreateTemporaryFileName(std::wstring* temp_file) {
   FilePath temp_file_path;
   if (!CreateTemporaryFileName(&temp_file_path))
@@ -390,6 +403,9 @@
 bool PathExists(const std::wstring& path) {
   return PathExists(FilePath::FromWStringHack(path));
 }
+bool PathIsWritable(const std::wstring& path) {
+  return PathIsWritable(FilePath::FromWStringHack(path));
+}
 bool SetCurrentDirectory(const std::wstring& directory) {
   return SetCurrentDirectory(FilePath::FromWStringHack(directory));
 }
diff --git a/base/file_util.h b/base/file_util.h
index d1cfb05..67cd59f 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -186,6 +186,8 @@
 bool PathExists(const std::wstring& path);
 
 // Returns true if the given path is writable by the user, false otherwise.
+bool PathIsWritable(const FilePath& path);
+// Deprecated temporary compatibility function.
 bool PathIsWritable(const std::wstring& path);
 
 // Returns true if the given path exists and is a directory, false otherwise.
@@ -273,7 +275,12 @@
 
 // Create a new directory under TempPath. If prefix is provided, the new
 // directory name is in the format of prefixyyyy.
+// NOTE: prefix is ignored in the POSIX implementation.
+// TODO(erikkay): is this OK?
 // If success, return true and output the full path of the directory created.
+bool CreateNewTempDirectory(const FilePath::StringType& prefix,
+                            FilePath* new_temp_path);
+// Deprecated temporary compatibility function.
 bool CreateNewTempDirectory(const std::wstring& prefix,
                             std::wstring* new_temp_path);
 
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 7448ed8..a05b053 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -85,7 +85,7 @@
           continue;
           break;
         case FTS_DP:
-          rmdir(fts_ent->fts_accpath);
+          success = (rmdir(fts_ent->fts_accpath) == 0);
           break;
         case FTS_D:
           break;
@@ -93,7 +93,7 @@
         case FTS_F:
         case FTS_SL:
         case FTS_SLNONE:
-          unlink(fts_ent->fts_accpath);
+          success = (unlink(fts_ent->fts_accpath) == 0);
           break;
         default:
           DCHECK(false);
@@ -215,6 +215,26 @@
   return (stat64(path.value().c_str(), &file_info) == 0);
 }
 
+bool PathIsWritable(const FilePath& path) {
+  FilePath test_path(path);
+  struct stat64 file_info;
+  if (stat64(test_path.value().c_str(), &file_info) != 0) {
+    // If the path doesn't exist, test the parent dir.
+    test_path = test_path.DirName();
+    // If the parent dir doesn't exist, then return false (the path is not
+    // directly writable).
+    if (stat64(test_path.value().c_str(), &file_info) != 0)
+      return false;
+  }
+  if (S_IWOTH & file_info.st_mode)
+    return true;
+  if (getegid() == file_info.st_gid && (S_IWGRP & file_info.st_mode))
+    return true;
+  if (geteuid() == file_info.st_uid && (S_IWUSR & file_info.st_mode))
+    return true;
+  return false;
+}
+
 bool DirectoryExists(const FilePath& path) {
   struct stat64 file_info;
   if (stat64(path.value().c_str(), &file_info) == 0)
@@ -274,8 +294,8 @@
   return false;
 }
 
-bool CreateNewTempDirectory(const std::wstring& prefix,
-                            std::wstring* new_temp_path) {
+bool CreateNewTempDirectory(const FilePath::StringType& prefix,
+                            FilePath* new_temp_path) {
   FilePath tmpdir;
   if (!GetTempDir(&tmpdir))
     return false;
@@ -286,7 +306,7 @@
   char* dtemp = mkdtemp(buffer);
   if (!dtemp)
     return false;
-  *new_temp_path = UTF8ToWide(dtemp);
+  *new_temp_path = FilePath(dtemp);
   return true;
 }