Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // This file contains utility functions for dealing with the local
      6 // filesystem.
      7 
      8 #ifndef BASE_FILE_UTIL_H_
      9 #define BASE_FILE_UTIL_H_
     10 
     11 #include "build/build_config.h"
     12 
     13 #if defined(OS_WIN)
     14 #include <windows.h>
     15 #elif defined(OS_POSIX)
     16 #include <sys/stat.h>
     17 #include <unistd.h>
     18 #endif
     19 
     20 #include <stdio.h>
     21 
     22 #include <set>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include "base/base_export.h"
     27 #include "base/basictypes.h"
     28 #include "base/files/file_path.h"
     29 #include "base/memory/scoped_ptr.h"
     30 #include "base/platform_file.h"
     31 #include "base/strings/string16.h"
     32 
     33 #if defined(OS_POSIX)
     34 #include "base/file_descriptor_posix.h"
     35 #include "base/logging.h"
     36 #include "base/posix/eintr_wrapper.h"
     37 #endif
     38 
     39 namespace base {
     40 
     41 class Time;
     42 
     43 //-----------------------------------------------------------------------------
     44 // Functions that involve filesystem access or modification:
     45 
     46 // Returns an absolute version of a relative path. Returns an empty path on
     47 // error. On POSIX, this function fails if the path does not exist. This
     48 // function can result in I/O so it can be slow.
     49 BASE_EXPORT FilePath MakeAbsoluteFilePath(const FilePath& input);
     50 
     51 // Returns the total number of bytes used by all the files under |root_path|.
     52 // If the path does not exist the function returns 0.
     53 //
     54 // This function is implemented using the FileEnumerator class so it is not
     55 // particularly speedy in any platform.
     56 BASE_EXPORT int64 ComputeDirectorySize(const FilePath& root_path);
     57 
     58 // Deletes the given path, whether it's a file or a directory.
     59 // If it's a directory, it's perfectly happy to delete all of the
     60 // directory's contents.  Passing true to recursive deletes
     61 // subdirectories and their contents as well.
     62 // Returns true if successful, false otherwise. It is considered successful
     63 // to attempt to delete a file that does not exist.
     64 //
     65 // In posix environment and if |path| is a symbolic link, this deletes only
     66 // the symlink. (even if the symlink points to a non-existent file)
     67 //
     68 // WARNING: USING THIS WITH recursive==true IS EQUIVALENT
     69 //          TO "rm -rf", SO USE WITH CAUTION.
     70 BASE_EXPORT bool DeleteFile(const FilePath& path, bool recursive);
     71 
     72 #if defined(OS_WIN)
     73 // Schedules to delete the given path, whether it's a file or a directory, until
     74 // the operating system is restarted.
     75 // Note:
     76 // 1) The file/directory to be deleted should exist in a temp folder.
     77 // 2) The directory to be deleted must be empty.
     78 BASE_EXPORT bool DeleteFileAfterReboot(const FilePath& path);
     79 #endif
     80 
     81 // Moves the given path, whether it's a file or a directory.
     82 // If a simple rename is not possible, such as in the case where the paths are
     83 // on different volumes, this will attempt to copy and delete. Returns
     84 // true for success.
     85 // This function fails if either path contains traversal components ('..').
     86 BASE_EXPORT bool Move(const FilePath& from_path, const FilePath& to_path);
     87 
     88 // Renames file |from_path| to |to_path|. Both paths must be on the same
     89 // volume, or the function will fail. Destination file will be created
     90 // if it doesn't exist. Prefer this function over Move when dealing with
     91 // temporary files. On Windows it preserves attributes of the target file.
     92 // Returns true on success, leaving *error unchanged.
     93 // Returns false on failure and sets *error appropriately, if it is non-NULL.
     94 BASE_EXPORT bool ReplaceFile(const FilePath& from_path,
     95                              const FilePath& to_path,
     96                              PlatformFileError* error);
     97 
     98 // Copies a single file. Use CopyDirectory to copy directories.
     99 // This function fails if either path contains traversal components ('..').
    100 BASE_EXPORT bool CopyFile(const FilePath& from_path, const FilePath& to_path);
    101 
    102 // Copies the given path, and optionally all subdirectories and their contents
    103 // as well.
    104 //
    105 // If there are files existing under to_path, always overwrite. Returns true
    106 // if successful, false otherwise. Wildcards on the names are not supported.
    107 //
    108 // If you only need to copy a file use CopyFile, it's faster.
    109 BASE_EXPORT bool CopyDirectory(const FilePath& from_path,
    110                                const FilePath& to_path,
    111                                bool recursive);
    112 
    113 // Returns true if the given path exists on the local filesystem,
    114 // false otherwise.
    115 BASE_EXPORT bool PathExists(const FilePath& path);
    116 
    117 // Returns true if the given path is writable by the user, false otherwise.
    118 BASE_EXPORT bool PathIsWritable(const FilePath& path);
    119 
    120 // Returns true if the given path exists and is a directory, false otherwise.
    121 BASE_EXPORT bool DirectoryExists(const FilePath& path);
    122 
    123 // Returns true if the contents of the two files given are equal, false
    124 // otherwise.  If either file can't be read, returns false.
    125 BASE_EXPORT bool ContentsEqual(const FilePath& filename1,
    126                                const FilePath& filename2);
    127 
    128 // Returns true if the contents of the two text files given are equal, false
    129 // otherwise.  This routine treats "\r\n" and "\n" as equivalent.
    130 BASE_EXPORT bool TextContentsEqual(const FilePath& filename1,
    131                                    const FilePath& filename2);
    132 
    133 // Read the file at |path| into |contents|, returning true on success.
    134 // This function fails if the |path| contains path traversal components ('..').
    135 // |contents| may be NULL, in which case this function is useful for its
    136 // side effect of priming the disk cache.
    137 // Useful for unit tests.
    138 BASE_EXPORT bool ReadFileToString(const FilePath& path, std::string* contents);
    139 
    140 #if defined(OS_POSIX)
    141 
    142 // Read exactly |bytes| bytes from file descriptor |fd|, storing the result
    143 // in |buffer|. This function is protected against EINTR and partial reads.
    144 // Returns true iff |bytes| bytes have been successfully read from |fd|.
    145 BASE_EXPORT bool ReadFromFD(int fd, char* buffer, size_t bytes);
    146 
    147 // Creates a symbolic link at |symlink| pointing to |target|.  Returns
    148 // false on failure.
    149 BASE_EXPORT bool CreateSymbolicLink(const FilePath& target,
    150                                     const FilePath& symlink);
    151 
    152 // Reads the given |symlink| and returns where it points to in |target|.
    153 // Returns false upon failure.
    154 BASE_EXPORT bool ReadSymbolicLink(const FilePath& symlink, FilePath* target);
    155 
    156 // Bits ans masks of the file permission.
    157 enum FilePermissionBits {
    158   FILE_PERMISSION_MASK              = S_IRWXU | S_IRWXG | S_IRWXO,
    159   FILE_PERMISSION_USER_MASK         = S_IRWXU,
    160   FILE_PERMISSION_GROUP_MASK        = S_IRWXG,
    161   FILE_PERMISSION_OTHERS_MASK       = S_IRWXO,
    162 
    163   FILE_PERMISSION_READ_BY_USER      = S_IRUSR,
    164   FILE_PERMISSION_WRITE_BY_USER     = S_IWUSR,
    165   FILE_PERMISSION_EXECUTE_BY_USER   = S_IXUSR,
    166   FILE_PERMISSION_READ_BY_GROUP     = S_IRGRP,
    167   FILE_PERMISSION_WRITE_BY_GROUP    = S_IWGRP,
    168   FILE_PERMISSION_EXECUTE_BY_GROUP  = S_IXGRP,
    169   FILE_PERMISSION_READ_BY_OTHERS    = S_IROTH,
    170   FILE_PERMISSION_WRITE_BY_OTHERS   = S_IWOTH,
    171   FILE_PERMISSION_EXECUTE_BY_OTHERS = S_IXOTH,
    172 };
    173 
    174 // Reads the permission of the given |path|, storing the file permission
    175 // bits in |mode|. If |path| is symbolic link, |mode| is the permission of
    176 // a file which the symlink points to.
    177 BASE_EXPORT bool GetPosixFilePermissions(const FilePath& path, int* mode);
    178 // Sets the permission of the given |path|. If |path| is symbolic link, sets
    179 // the permission of a file which the symlink points to.
    180 BASE_EXPORT bool SetPosixFilePermissions(const FilePath& path, int mode);
    181 
    182 #endif  // OS_POSIX
    183 
    184 // Returns true if the given directory is empty
    185 BASE_EXPORT bool IsDirectoryEmpty(const FilePath& dir_path);
    186 
    187 // Get the temporary directory provided by the system.
    188 //
    189 // WARNING: In general, you should use CreateTemporaryFile variants below
    190 // instead of this function. Those variants will ensure that the proper
    191 // permissions are set so that other users on the system can't edit them while
    192 // they're open (which can lead to security issues).
    193 BASE_EXPORT bool GetTempDir(FilePath* path);
    194 
    195 // Get a temporary directory for shared memory files. The directory may depend
    196 // on whether the destination is intended for executable files, which in turn
    197 // depends on how /dev/shmem was mounted. As a result, you must supply whether
    198 // you intend to create executable shmem segments so this function can find
    199 // an appropriate location.
    200 //
    201 // Only useful on POSIX; redirects to GetTempDir() on Windows.
    202 BASE_EXPORT bool GetShmemTempDir(bool executable, FilePath* path);
    203 
    204 #if defined(OS_POSIX)
    205 // Get the home directory.  This is more complicated than just getenv("HOME")
    206 // as it knows to fall back on getpwent() etc.
    207 //
    208 // This function is not currently implemented on Windows or Mac because we
    209 // don't use it. Generally you would use one of PathService's APP_DATA
    210 // directories on those platforms. If we need it, this could be implemented
    211 // there to return the appropriate directory.
    212 BASE_EXPORT FilePath GetHomeDir();
    213 #endif  // OS_POSIX
    214 
    215 // Creates a temporary file. The full path is placed in |path|, and the
    216 // function returns true if was successful in creating the file. The file will
    217 // be empty and all handles closed after this function returns.
    218 BASE_EXPORT bool CreateTemporaryFile(FilePath* path);
    219 
    220 // Same as CreateTemporaryFile but the file is created in |dir|.
    221 BASE_EXPORT bool CreateTemporaryFileInDir(const FilePath& dir,
    222                                           FilePath* temp_file);
    223 
    224 // Create and open a temporary file.  File is opened for read/write.
    225 // The full path is placed in |path|.
    226 // Returns a handle to the opened file or NULL if an error occurred.
    227 BASE_EXPORT FILE* CreateAndOpenTemporaryFile(FilePath* path);
    228 
    229 // Like above but for shmem files.  Only useful for POSIX.
    230 // The executable flag says the file needs to support using
    231 // mprotect with PROT_EXEC after mapping.
    232 BASE_EXPORT FILE* CreateAndOpenTemporaryShmemFile(FilePath* path,
    233                                                   bool executable);
    234 
    235 // Similar to CreateAndOpenTemporaryFile, but the file is created in |dir|.
    236 BASE_EXPORT FILE* CreateAndOpenTemporaryFileInDir(const FilePath& dir,
    237                                                   FilePath* path);
    238 
    239 // Create a new directory. If prefix is provided, the new directory name is in
    240 // the format of prefixyyyy.
    241 // NOTE: prefix is ignored in the POSIX implementation.
    242 // If success, return true and output the full path of the directory created.
    243 BASE_EXPORT bool CreateNewTempDirectory(const FilePath::StringType& prefix,
    244                                         FilePath* new_temp_path);
    245 
    246 // Create a directory within another directory.
    247 // Extra characters will be appended to |prefix| to ensure that the
    248 // new directory does not have the same name as an existing directory.
    249 BASE_EXPORT bool CreateTemporaryDirInDir(const FilePath& base_dir,
    250                                          const FilePath::StringType& prefix,
    251                                          FilePath* new_dir);
    252 
    253 // Creates a directory, as well as creating any parent directories, if they
    254 // don't exist. Returns 'true' on successful creation, or if the directory
    255 // already exists.  The directory is only readable by the current user.
    256 // Returns true on success, leaving *error unchanged.
    257 // Returns false on failure and sets *error appropriately, if it is non-NULL.
    258 BASE_EXPORT bool CreateDirectoryAndGetError(const FilePath& full_path,
    259                                             PlatformFileError* error);
    260 
    261 // Backward-compatible convenience method for the above.
    262 BASE_EXPORT bool CreateDirectory(const FilePath& full_path);
    263 
    264 // Returns the file size. Returns true on success.
    265 BASE_EXPORT bool GetFileSize(const FilePath& file_path, int64* file_size);
    266 
    267 // Sets |real_path| to |path| with symbolic links and junctions expanded.
    268 // On windows, make sure the path starts with a lettered drive.
    269 // |path| must reference a file.  Function will fail if |path| points to
    270 // a directory or to a nonexistent path.  On windows, this function will
    271 // fail if |path| is a junction or symlink that points to an empty file,
    272 // or if |real_path| would be longer than MAX_PATH characters.
    273 BASE_EXPORT bool NormalizeFilePath(const FilePath& path, FilePath* real_path);
    274 
    275 #if defined(OS_WIN)
    276 
    277 // Given a path in NT native form ("\Device\HarddiskVolumeXX\..."),
    278 // return in |drive_letter_path| the equivalent path that starts with
    279 // a drive letter ("C:\...").  Return false if no such path exists.
    280 BASE_EXPORT bool DevicePathToDriveLetterPath(const FilePath& device_path,
    281                                              FilePath* drive_letter_path);
    282 
    283 // Given an existing file in |path|, set |real_path| to the path
    284 // in native NT format, of the form "\Device\HarddiskVolumeXX\..".
    285 // Returns false if the path can not be found. Empty files cannot
    286 // be resolved with this function.
    287 BASE_EXPORT bool NormalizeToNativeFilePath(const FilePath& path,
    288                                            FilePath* nt_path);
    289 #endif
    290 
    291 // This function will return if the given file is a symlink or not.
    292 BASE_EXPORT bool IsLink(const FilePath& file_path);
    293 
    294 // Returns information about the given file path.
    295 BASE_EXPORT bool GetFileInfo(const FilePath& file_path, PlatformFileInfo* info);
    296 
    297 // Sets the time of the last access and the time of the last modification.
    298 BASE_EXPORT bool TouchFile(const FilePath& path,
    299                            const Time& last_accessed,
    300                            const Time& last_modified);
    301 
    302 // Wrapper for fopen-like calls. Returns non-NULL FILE* on success.
    303 BASE_EXPORT FILE* OpenFile(const FilePath& filename, const char* mode);
    304 
    305 // Closes file opened by OpenFile. Returns true on success.
    306 BASE_EXPORT bool CloseFile(FILE* file);
    307 
    308 // Truncates an open file to end at the location of the current file pointer.
    309 // This is a cross-platform analog to Windows' SetEndOfFile() function.
    310 BASE_EXPORT bool TruncateFile(FILE* file);
    311 
    312 // Reads the given number of bytes from the file into the buffer.  Returns
    313 // the number of read bytes, or -1 on error.
    314 BASE_EXPORT int ReadFile(const base::FilePath& filename, char* data, int size);
    315 
    316 }  // namespace base
    317 
    318 // -----------------------------------------------------------------------------
    319 
    320 namespace file_util {
    321 
    322 // Writes the given buffer into the file, overwriting any data that was
    323 // previously there.  Returns the number of bytes written, or -1 on error.
    324 BASE_EXPORT int WriteFile(const base::FilePath& filename, const char* data,
    325                           int size);
    326 #if defined(OS_POSIX)
    327 // Append the data to |fd|. Does not close |fd| when done.
    328 BASE_EXPORT int WriteFileDescriptor(const int fd, const char* data, int size);
    329 #endif
    330 // Append the given buffer into the file. Returns the number of bytes written,
    331 // or -1 on error.
    332 BASE_EXPORT int AppendToFile(const base::FilePath& filename,
    333                              const char* data, int size);
    334 
    335 // Gets the current working directory for the process.
    336 BASE_EXPORT bool GetCurrentDirectory(base::FilePath* path);
    337 
    338 // Sets the current working directory for the process.
    339 BASE_EXPORT bool SetCurrentDirectory(const base::FilePath& path);
    340 
    341 // Attempts to find a number that can be appended to the |path| to make it
    342 // unique. If |path| does not exist, 0 is returned.  If it fails to find such
    343 // a number, -1 is returned. If |suffix| is not empty, also checks the
    344 // existence of it with the given suffix.
    345 BASE_EXPORT int GetUniquePathNumber(const base::FilePath& path,
    346                                     const base::FilePath::StringType& suffix);
    347 
    348 #if defined(OS_POSIX)
    349 // Creates a directory with a guaranteed unique name based on |path|, returning
    350 // the pathname if successful, or an empty path if there was an error creating
    351 // the directory. Does not create parent directories.
    352 BASE_EXPORT base::FilePath MakeUniqueDirectory(const base::FilePath& path);
    353 #endif
    354 
    355 #if defined(OS_POSIX)
    356 // Test that |path| can only be changed by a given user and members of
    357 // a given set of groups.
    358 // Specifically, test that all parts of |path| under (and including) |base|:
    359 // * Exist.
    360 // * Are owned by a specific user.
    361 // * Are not writable by all users.
    362 // * Are owned by a member of a given set of groups, or are not writable by
    363 //   their group.
    364 // * Are not symbolic links.
    365 // This is useful for checking that a config file is administrator-controlled.
    366 // |base| must contain |path|.
    367 BASE_EXPORT bool VerifyPathControlledByUser(const base::FilePath& base,
    368                                             const base::FilePath& path,
    369                                             uid_t owner_uid,
    370                                             const std::set<gid_t>& group_gids);
    371 #endif  // defined(OS_POSIX)
    372 
    373 #if defined(OS_MACOSX) && !defined(OS_IOS)
    374 // Is |path| writable only by a user with administrator privileges?
    375 // This function uses Mac OS conventions.  The super user is assumed to have
    376 // uid 0, and the administrator group is assumed to be named "admin".
    377 // Testing that |path|, and every parent directory including the root of
    378 // the filesystem, are owned by the superuser, controlled by the group
    379 // "admin", are not writable by all users, and contain no symbolic links.
    380 // Will return false if |path| does not exist.
    381 BASE_EXPORT bool VerifyPathControlledByAdmin(const base::FilePath& path);
    382 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
    383 
    384 // Returns the maximum length of path component on the volume containing
    385 // the directory |path|, in the number of FilePath::CharType, or -1 on failure.
    386 BASE_EXPORT int GetMaximumPathComponentLength(const base::FilePath& path);
    387 
    388 // A class to handle auto-closing of FILE*'s.
    389 class ScopedFILEClose {
    390  public:
    391   inline void operator()(FILE* x) const {
    392     if (x) {
    393       fclose(x);
    394     }
    395   }
    396 };
    397 
    398 typedef scoped_ptr_malloc<FILE, ScopedFILEClose> ScopedFILE;
    399 
    400 #if defined(OS_POSIX)
    401 // A class to handle auto-closing of FDs.
    402 class ScopedFDClose {
    403  public:
    404   inline void operator()(int* x) const {
    405     if (x && *x >= 0) {
    406       if (IGNORE_EINTR(close(*x)) < 0)
    407         DPLOG(ERROR) << "close";
    408     }
    409   }
    410 };
    411 
    412 typedef scoped_ptr_malloc<int, ScopedFDClose> ScopedFD;
    413 #endif  // OS_POSIX
    414 
    415 #if defined(OS_LINUX)
    416 // Broad categories of file systems as returned by statfs() on Linux.
    417 enum FileSystemType {
    418   FILE_SYSTEM_UNKNOWN,  // statfs failed.
    419   FILE_SYSTEM_0,        // statfs.f_type == 0 means unknown, may indicate AFS.
    420   FILE_SYSTEM_ORDINARY,       // on-disk filesystem like ext2
    421   FILE_SYSTEM_NFS,
    422   FILE_SYSTEM_SMB,
    423   FILE_SYSTEM_CODA,
    424   FILE_SYSTEM_MEMORY,         // in-memory file system
    425   FILE_SYSTEM_CGROUP,         // cgroup control.
    426   FILE_SYSTEM_OTHER,          // any other value.
    427   FILE_SYSTEM_TYPE_COUNT
    428 };
    429 
    430 // Attempts determine the FileSystemType for |path|.
    431 // Returns false if |path| doesn't exist.
    432 BASE_EXPORT bool GetFileSystemType(const base::FilePath& path,
    433                                    FileSystemType* type);
    434 #endif
    435 
    436 }  // namespace file_util
    437 
    438 // Internal --------------------------------------------------------------------
    439 
    440 namespace base {
    441 namespace internal {
    442 
    443 // Same as Move but allows paths with traversal components.
    444 // Use only with extreme care.
    445 BASE_EXPORT bool MoveUnsafe(const FilePath& from_path,
    446                             const FilePath& to_path);
    447 
    448 // Same as CopyFile but allows paths with traversal components.
    449 // Use only with extreme care.
    450 BASE_EXPORT bool CopyFileUnsafe(const FilePath& from_path,
    451                                 const FilePath& to_path);
    452 
    453 #if defined(OS_WIN)
    454 // Copy from_path to to_path recursively and then delete from_path recursively.
    455 // Returns true if all operations succeed.
    456 // This function simulates Move(), but unlike Move() it works across volumes.
    457 // This function is not transactional.
    458 BASE_EXPORT bool CopyAndDeleteDirectory(const FilePath& from_path,
    459                                         const FilePath& to_path);
    460 #endif  // defined(OS_WIN)
    461 
    462 }  // namespace internal
    463 }  // namespace base
    464 
    465 #endif  // BASE_FILE_UTIL_H_
    466