Index: base/file_util_posix.cc |
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc |
index 027337f32c6f90e217bc5e4cc62e2aefca5b7a49..b6a4945b7b30dc47457b1c118910100608d7714a 100644 |
--- a/base/file_util_posix.cc |
+++ b/base/file_util_posix.cc |
@@ -150,6 +150,47 @@ std::string TempFileName() { |
#endif |
} |
+// Creates and opens a temporary file in |directory|, returning the |
+// file descriptor. |path| is set to the temporary file path. |
+// This function does NOT unlink() the file. |
+int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { |
+ ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp(). |
+ *path = directory.Append(base::TempFileName()); |
+ const std::string& tmpdir_string = path->value(); |
+ // this should be OK since mkstemp just replaces characters in place |
+ char* buffer = const_cast<char*>(tmpdir_string.c_str()); |
+ |
+ return HANDLE_EINTR(mkstemp(buffer)); |
+} |
+ |
+#if defined(OS_LINUX) |
+// Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC. |
+// This depends on the mount options used for /dev/shm, which vary among |
+// different Linux distributions and possibly local configuration. It also |
+// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm |
+// but its kernel allows mprotect with PROT_EXEC anyway. |
+bool DetermineDevShmExecutable() { |
+ bool result = false; |
+ FilePath path; |
+ int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path); |
+ if (fd >= 0) { |
+ file_util::ScopedFD shm_fd_closer(&fd); |
+ DeleteFile(path, false); |
+ long sysconf_result = sysconf(_SC_PAGESIZE); |
+ CHECK_GE(sysconf_result, 0); |
+ size_t pagesize = static_cast<size_t>(sysconf_result); |
+ CHECK_GE(sizeof(pagesize), sizeof(sysconf_result)); |
+ void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); |
+ if (mapping != MAP_FAILED) { |
+ if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0) |
+ result = true; |
+ munmap(mapping, pagesize); |
+ } |
+ } |
+ return result; |
+} |
+#endif // defined(OS_LINUX) |
+ |
} // namespace |
FilePath MakeAbsoluteFilePath(const FilePath& input) { |
@@ -405,6 +446,73 @@ bool SetPosixFilePermissions(const FilePath& path, |
return true; |
} |
+#if !defined(OS_MACOSX) |
+// This is implemented in file_util_mac.mm for Mac. |
+bool GetTempDir(FilePath* path) { |
+ const char* tmp = getenv("TMPDIR"); |
+ if (tmp) { |
+ *path = FilePath(tmp); |
+ } else { |
+#if defined(OS_ANDROID) |
+ return PathService::Get(base::DIR_CACHE, path); |
+#else |
+ *path = FilePath("/tmp"); |
+#endif |
+ } |
+ return true; |
+} |
+#endif // !defined(OS_MACOSX) |
+ |
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
+// This is implemented in file_util_mac.mm and file_util_android.cc for those |
+// platforms. |
+bool GetShmemTempDir(bool executable, FilePath* path) { |
+#if defined(OS_LINUX) |
+ bool use_dev_shm = true; |
+ if (executable) { |
+ static const bool s_dev_shm_executable = DetermineDevShmExecutable(); |
+ use_dev_shm = s_dev_shm_executable; |
+ } |
+ if (use_dev_shm) { |
+ *path = FilePath("/dev/shm"); |
+ return true; |
+ } |
+#endif |
+ return GetTempDir(path); |
+} |
+#endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) |
+ |
+#if !defined(OS_MACOSX) |
+FilePath GetHomeDir() { |
+#if defined(OS_CHROMEOS) |
+ if (SysInfo::IsRunningOnChromeOS()) |
+ return FilePath("/home/chronos/user"); |
+#endif |
+ |
+ const char* home_dir = getenv("HOME"); |
+ if (home_dir && home_dir[0]) |
+ return FilePath(home_dir); |
+ |
+#if defined(OS_ANDROID) |
+ DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; |
+#elif defined(USE_GLIB) && !defined(OS_CHROMEOS) |
+ // g_get_home_dir calls getpwent, which can fall through to LDAP calls. |
+ ThreadRestrictions::AssertIOAllowed(); |
+ |
+ home_dir = g_get_home_dir(); |
+ if (home_dir && home_dir[0]) |
+ return FilePath(home_dir); |
+#endif |
+ |
+ FilePath rv; |
+ if (GetTempDir(&rv)) |
+ return rv; |
+ |
+ // Last resort. |
+ return FilePath("/tmp"); |
+} |
+#endif // !defined(OS_MACOSX) |
+ |
} // namespace base |
// ----------------------------------------------------------------------------- |
@@ -414,6 +522,7 @@ namespace file_util { |
using base::stat_wrapper_t; |
using base::CallStat; |
using base::CallLstat; |
+using base::CreateAndOpenFdForTemporaryFile; |
using base::DirectoryExists; |
using base::FileEnumerator; |
using base::FilePath; |
@@ -421,19 +530,6 @@ using base::MakeAbsoluteFilePath; |
using base::RealPath; |
using base::VerifySpecificPathControlledByUser; |
-// Creates and opens a temporary file in |directory|, returning the |
-// file descriptor. |path| is set to the temporary file path. |
-// This function does NOT unlink() the file. |
-int CreateAndOpenFdForTemporaryFile(FilePath directory, FilePath* path) { |
- base::ThreadRestrictions::AssertIOAllowed(); // For call to mkstemp(). |
- *path = directory.Append(base::TempFileName()); |
- const std::string& tmpdir_string = path->value(); |
- // this should be OK since mkstemp just replaces characters in place |
- char* buffer = const_cast<char*>(tmpdir_string.c_str()); |
- |
- return HANDLE_EINTR(mkstemp(buffer)); |
-} |
- |
bool CreateTemporaryFile(FilePath* path) { |
base::ThreadRestrictions::AssertIOAllowed(); // For call to close(). |
FilePath directory; |
@@ -448,7 +544,7 @@ bool CreateTemporaryFile(FilePath* path) { |
FILE* CreateAndOpenTemporaryShmemFile(FilePath* path, bool executable) { |
FilePath directory; |
- if (!GetShmemTempDir(&directory, executable)) |
+ if (!GetShmemTempDir(executable, &directory)) |
return NULL; |
return CreateAndOpenTemporaryFileInDir(directory, path); |
@@ -725,101 +821,6 @@ bool NormalizeFilePath(const FilePath& path, FilePath* normalized_path) { |
return true; |
} |
-#if !defined(OS_MACOSX) |
-bool GetTempDir(FilePath* path) { |
- const char* tmp = getenv("TMPDIR"); |
- if (tmp) |
- *path = FilePath(tmp); |
- else |
-#if defined(OS_ANDROID) |
- return PathService::Get(base::DIR_CACHE, path); |
-#else |
- *path = FilePath("/tmp"); |
-#endif |
- return true; |
-} |
- |
-#if !defined(OS_ANDROID) |
- |
-#if defined(OS_LINUX) |
-// Determine if /dev/shm files can be mapped and then mprotect'd PROT_EXEC. |
-// This depends on the mount options used for /dev/shm, which vary among |
-// different Linux distributions and possibly local configuration. It also |
-// depends on details of kernel--ChromeOS uses the noexec option for /dev/shm |
-// but its kernel allows mprotect with PROT_EXEC anyway. |
- |
-namespace { |
- |
-bool DetermineDevShmExecutable() { |
- bool result = false; |
- FilePath path; |
- int fd = CreateAndOpenFdForTemporaryFile(FilePath("/dev/shm"), &path); |
- if (fd >= 0) { |
- ScopedFD shm_fd_closer(&fd); |
- DeleteFile(path, false); |
- long sysconf_result = sysconf(_SC_PAGESIZE); |
- CHECK_GE(sysconf_result, 0); |
- size_t pagesize = static_cast<size_t>(sysconf_result); |
- CHECK_GE(sizeof(pagesize), sizeof(sysconf_result)); |
- void *mapping = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, 0); |
- if (mapping != MAP_FAILED) { |
- if (mprotect(mapping, pagesize, PROT_READ | PROT_EXEC) == 0) |
- result = true; |
- munmap(mapping, pagesize); |
- } |
- } |
- return result; |
-} |
- |
-}; // namespace |
-#endif // defined(OS_LINUX) |
- |
-bool GetShmemTempDir(FilePath* path, bool executable) { |
-#if defined(OS_LINUX) |
- bool use_dev_shm = true; |
- if (executable) { |
- static const bool s_dev_shm_executable = DetermineDevShmExecutable(); |
- use_dev_shm = s_dev_shm_executable; |
- } |
- if (use_dev_shm) { |
- *path = FilePath("/dev/shm"); |
- return true; |
- } |
-#endif |
- return GetTempDir(path); |
-} |
-#endif // !defined(OS_ANDROID) |
- |
-FilePath GetHomeDir() { |
-#if defined(OS_CHROMEOS) |
- if (base::SysInfo::IsRunningOnChromeOS()) |
- return FilePath("/home/chronos/user"); |
-#endif |
- |
- const char* home_dir = getenv("HOME"); |
- if (home_dir && home_dir[0]) |
- return FilePath(home_dir); |
- |
-#if defined(OS_ANDROID) |
- DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; |
-#elif defined(USE_GLIB) && !defined(OS_CHROMEOS) |
- // g_get_home_dir calls getpwent, which can fall through to LDAP calls. |
- base::ThreadRestrictions::AssertIOAllowed(); |
- |
- home_dir = g_get_home_dir(); |
- if (home_dir && home_dir[0]) |
- return FilePath(home_dir); |
-#endif |
- |
- FilePath rv; |
- if (file_util::GetTempDir(&rv)) |
- return rv; |
- |
- // Last resort. |
- return FilePath("/tmp"); |
-} |
-#endif // !defined(OS_MACOSX) |
- |
bool VerifyPathControlledByUser(const FilePath& base, |
const FilePath& path, |
uid_t owner_uid, |