LLVM API Documentation

FileSystem.h
Go to the documentation of this file.
00001 //===- llvm/Support/FileSystem.h - File System OS Concept -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file declares the llvm::sys::fs namespace. It is designed after
00011 // TR2/boost filesystem (v3), but modified to remove exception handling and the
00012 // path class.
00013 //
00014 // All functions return an error_code and their actual work via the last out
00015 // argument. The out argument is defined if and only if errc::success is
00016 // returned. A function may return any error code in the generic or system
00017 // category. However, they shall be equivalent to any error conditions listed
00018 // in each functions respective documentation if the condition applies. [ note:
00019 // this does not guarantee that error_code will be in the set of explicitly
00020 // listed codes, but it does guarantee that if any of the explicitly listed
00021 // errors occur, the correct error_code will be used ]. All functions may
00022 // return errc::not_enough_memory if there is not enough memory to complete the
00023 // operation.
00024 //
00025 //===----------------------------------------------------------------------===//
00026 
00027 #ifndef LLVM_SUPPORT_FILESYSTEM_H
00028 #define LLVM_SUPPORT_FILESYSTEM_H
00029 
00030 #include "llvm/ADT/IntrusiveRefCntPtr.h"
00031 #include "llvm/ADT/OwningPtr.h"
00032 #include "llvm/ADT/SmallString.h"
00033 #include "llvm/ADT/Twine.h"
00034 #include "llvm/Support/DataTypes.h"
00035 #include "llvm/Support/ErrorHandling.h"
00036 #include "llvm/Support/system_error.h"
00037 #include <ctime>
00038 #include <iterator>
00039 #include <stack>
00040 #include <string>
00041 #include <vector>
00042 
00043 #ifdef HAVE_SYS_STAT_H
00044 #include <sys/stat.h>
00045 #endif
00046 
00047 namespace llvm {
00048 namespace sys {
00049 namespace fs {
00050 
00051 /// file_type - An "enum class" enumeration for the file system's view of the
00052 ///             type.
00053 struct file_type {
00054   enum _ {
00055     status_error,
00056     file_not_found,
00057     regular_file,
00058     directory_file,
00059     symlink_file,
00060     block_file,
00061     character_file,
00062     fifo_file,
00063     socket_file,
00064     type_unknown
00065   };
00066 
00067   file_type(_ v) : v_(v) {}
00068   explicit file_type(int v) : v_(_(v)) {}
00069   operator int() const {return v_;}
00070 
00071 private:
00072   int v_;
00073 };
00074 
00075 /// copy_option - An "enum class" enumeration of copy semantics for copy
00076 ///               operations.
00077 struct copy_option {
00078   enum _ {
00079     fail_if_exists,
00080     overwrite_if_exists
00081   };
00082 
00083   copy_option(_ v) : v_(v) {}
00084   explicit copy_option(int v) : v_(_(v)) {}
00085   operator int() const {return v_;}
00086 
00087 private:
00088   int v_;
00089 };
00090 
00091 /// space_info - Self explanatory.
00092 struct space_info {
00093   uint64_t capacity;
00094   uint64_t free;
00095   uint64_t available;
00096 };
00097 
00098 
00099 enum perms {
00100   no_perms     = 0,
00101   owner_read   = 0400, 
00102   owner_write  = 0200, 
00103   owner_exe    = 0100, 
00104   owner_all    = owner_read | owner_write | owner_exe,
00105   group_read   =  040, 
00106   group_write  =  020, 
00107   group_exe    =  010, 
00108   group_all    = group_read | group_write | group_exe,
00109   others_read  =   04, 
00110   others_write =   02, 
00111   others_exe   =   01, 
00112   others_all   = others_read | others_write | others_exe, 
00113   all_all      = owner_all | group_all | others_all,
00114   set_uid_on_exe  = 04000, 
00115   set_gid_on_exe  = 02000, 
00116   sticky_bit      = 01000,
00117   perms_mask      = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, 
00118   perms_not_known = 0xFFFF,
00119   add_perms       = 0x1000,
00120   remove_perms    = 0x2000, 
00121   symlink_perms   = 0x4000
00122 };
00123 
00124 // Helper functions so that you can use & and | to manipulate perms bits:
00125 inline perms operator|(perms l , perms r) {
00126   return static_cast<perms>(
00127              static_cast<unsigned short>(l) | static_cast<unsigned short>(r)); 
00128 }
00129 inline perms operator&(perms l , perms r) {
00130   return static_cast<perms>(
00131              static_cast<unsigned short>(l) & static_cast<unsigned short>(r)); 
00132 }
00133 inline perms &operator|=(perms &l, perms r) {
00134   l = l | r; 
00135   return l; 
00136 }
00137 inline perms &operator&=(perms &l, perms r) {
00138   l = l & r; 
00139   return l; 
00140 }
00141 inline perms operator~(perms x) {
00142   return static_cast<perms>(~static_cast<unsigned short>(x));
00143 }
00144 
00145 
00146  
00147 /// file_status - Represents the result of a call to stat and friends. It has
00148 ///               a platform specific member to store the result.
00149 class file_status
00150 {
00151   #if defined(LLVM_ON_UNIX)
00152   dev_t fs_st_dev;
00153   ino_t fs_st_ino;
00154   #elif defined (LLVM_ON_WIN32)
00155   uint32_t LastWriteTimeHigh;
00156   uint32_t LastWriteTimeLow;
00157   uint32_t VolumeSerialNumber;
00158   uint32_t FileSizeHigh;
00159   uint32_t FileSizeLow;
00160   uint32_t FileIndexHigh;
00161   uint32_t FileIndexLow;
00162   #endif
00163   friend bool equivalent(file_status A, file_status B);
00164   friend error_code status(const Twine &path, file_status &result);
00165   file_type Type;
00166   perms Perms;
00167 public:
00168   explicit file_status(file_type v=file_type::status_error, 
00169                       perms prms=perms_not_known)
00170     : Type(v), Perms(prms) {}
00171 
00172   // getters
00173   file_type type() const { return Type; }
00174   perms permissions() const { return Perms; }
00175   
00176   // setters
00177   void type(file_type v) { Type = v; }
00178   void permissions(perms p) { Perms = p; }
00179 };
00180 
00181 /// file_magic - An "enum class" enumeration of file types based on magic (the first
00182 ///         N bytes of the file).
00183 struct file_magic {
00184   enum _ {
00185     unknown = 0,              ///< Unrecognized file
00186     bitcode,                  ///< Bitcode file
00187     archive,                  ///< ar style archive file
00188     elf_relocatable,          ///< ELF Relocatable object file
00189     elf_executable,           ///< ELF Executable image
00190     elf_shared_object,        ///< ELF dynamically linked shared lib
00191     elf_core,                 ///< ELF core image
00192     macho_object,             ///< Mach-O Object file
00193     macho_executable,         ///< Mach-O Executable
00194     macho_fixed_virtual_memory_shared_lib, ///< Mach-O Shared Lib, FVM
00195     macho_core,               ///< Mach-O Core File
00196     macho_preload_executabl,  ///< Mach-O Preloaded Executable
00197     macho_dynamically_linked_shared_lib, ///< Mach-O dynlinked shared lib
00198     macho_dynamic_linker,     ///< The Mach-O dynamic linker
00199     macho_bundle,             ///< Mach-O Bundle file
00200     macho_dynamically_linked_shared_lib_stub, ///< Mach-O Shared lib stub
00201     macho_dsym_companion,     ///< Mach-O dSYM companion file
00202     coff_object,              ///< COFF object file
00203     pecoff_executable         ///< PECOFF executable file
00204   };
00205 
00206   bool is_object() const {
00207     return v_ == unknown ? false : true;
00208   }
00209 
00210   file_magic() : v_(unknown) {}
00211   file_magic(_ v) : v_(v) {}
00212   explicit file_magic(int v) : v_(_(v)) {}
00213   operator int() const {return v_;}
00214 
00215 private:
00216   int v_;
00217 };
00218 
00219 /// @}
00220 /// @name Physical Operators
00221 /// @{
00222 
00223 /// @brief Make \a path an absolute path.
00224 ///
00225 /// Makes \a path absolute using the current directory if it is not already. An
00226 /// empty \a path will result in the current directory.
00227 ///
00228 /// /absolute/path   => /absolute/path
00229 /// relative/../path => <current-directory>/relative/../path
00230 ///
00231 /// @param path A path that is modified to be an absolute path.
00232 /// @returns errc::success if \a path has been made absolute, otherwise a
00233 ///          platform specific error_code.
00234 error_code make_absolute(SmallVectorImpl<char> &path);
00235 
00236 /// @brief Copy the file at \a from to the path \a to.
00237 ///
00238 /// @param from The path to copy the file from.
00239 /// @param to The path to copy the file to.
00240 /// @param copt Behavior if \a to already exists.
00241 /// @returns errc::success if the file has been successfully copied.
00242 ///          errc::file_exists if \a to already exists and \a copt ==
00243 ///          copy_option::fail_if_exists. Otherwise a platform specific
00244 ///          error_code.
00245 error_code copy_file(const Twine &from, const Twine &to,
00246                      copy_option copt = copy_option::fail_if_exists);
00247 
00248 /// @brief Create all the non-existent directories in path.
00249 ///
00250 /// @param path Directories to create.
00251 /// @param existed Set to true if \a path already existed, false otherwise.
00252 /// @returns errc::success if is_directory(path) and existed have been set,
00253 ///          otherwise a platform specific error_code.
00254 error_code create_directories(const Twine &path, bool &existed);
00255 
00256 /// @brief Create the directory in path.
00257 ///
00258 /// @param path Directory to create.
00259 /// @param existed Set to true if \a path already existed, false otherwise.
00260 /// @returns errc::success if is_directory(path) and existed have been set,
00261 ///          otherwise a platform specific error_code.
00262 error_code create_directory(const Twine &path, bool &existed);
00263 
00264 /// @brief Create a hard link from \a from to \a to.
00265 ///
00266 /// @param to The path to hard link to.
00267 /// @param from The path to hard link from. This is created.
00268 /// @returns errc::success if exists(to) && exists(from) && equivalent(to, from)
00269 ///          , otherwise a platform specific error_code.
00270 error_code create_hard_link(const Twine &to, const Twine &from);
00271 
00272 /// @brief Create a symbolic link from \a from to \a to.
00273 ///
00274 /// @param to The path to symbolically link to.
00275 /// @param from The path to symbolically link from. This is created.
00276 /// @returns errc::success if exists(to) && exists(from) && is_symlink(from),
00277 ///          otherwise a platform specific error_code.
00278 error_code create_symlink(const Twine &to, const Twine &from);
00279 
00280 /// @brief Get the current path.
00281 ///
00282 /// @param result Holds the current path on return.
00283 /// @returns errc::success if the current path has been stored in result,
00284 ///          otherwise a platform specific error_code.
00285 error_code current_path(SmallVectorImpl<char> &result);
00286 
00287 /// @brief Remove path. Equivalent to POSIX remove().
00288 ///
00289 /// @param path Input path.
00290 /// @param existed Set to true if \a path existed, false if it did not.
00291 ///                undefined otherwise.
00292 /// @returns errc::success if path has been removed and existed has been
00293 ///          successfully set, otherwise a platform specific error_code.
00294 error_code remove(const Twine &path, bool &existed);
00295 
00296 /// @brief Recursively remove all files below \a path, then \a path. Files are
00297 ///        removed as if by POSIX remove().
00298 ///
00299 /// @param path Input path.
00300 /// @param num_removed Number of files removed.
00301 /// @returns errc::success if path has been removed and num_removed has been
00302 ///          successfully set, otherwise a platform specific error_code.
00303 error_code remove_all(const Twine &path, uint32_t &num_removed);
00304 
00305 /// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename().
00306 ///
00307 /// @param from The path to rename from.
00308 /// @param to The path to rename to. This is created.
00309 error_code rename(const Twine &from, const Twine &to);
00310 
00311 /// @brief Resize path to size. File is resized as if by POSIX truncate().
00312 ///
00313 /// @param path Input path.
00314 /// @param size Size to resize to.
00315 /// @returns errc::success if \a path has been resized to \a size, otherwise a
00316 ///          platform specific error_code.
00317 error_code resize_file(const Twine &path, uint64_t size);
00318 
00319 /// @}
00320 /// @name Physical Observers
00321 /// @{
00322 
00323 /// @brief Does file exist?
00324 ///
00325 /// @param status A file_status previously returned from stat.
00326 /// @returns True if the file represented by status exists, false if it does
00327 ///          not.
00328 bool exists(file_status status);
00329 
00330 /// @brief Does file exist?
00331 ///
00332 /// @param path Input path.
00333 /// @param result Set to true if the file represented by status exists, false if
00334 ///               it does not. Undefined otherwise.
00335 /// @returns errc::success if result has been successfully set, otherwise a
00336 ///          platform specific error_code.
00337 error_code exists(const Twine &path, bool &result);
00338 
00339 /// @brief Simpler version of exists for clients that don't need to
00340 ///        differentiate between an error and false.
00341 inline bool exists(const Twine &path) {
00342   bool result;
00343   return !exists(path, result) && result;
00344 }
00345 
00346 /// @brief Do file_status's represent the same thing?
00347 ///
00348 /// @param A Input file_status.
00349 /// @param B Input file_status.
00350 ///
00351 /// assert(status_known(A) || status_known(B));
00352 ///
00353 /// @returns True if A and B both represent the same file system entity, false
00354 ///          otherwise.
00355 bool equivalent(file_status A, file_status B);
00356 
00357 /// @brief Do paths represent the same thing?
00358 ///
00359 /// assert(status_known(A) || status_known(B));
00360 ///
00361 /// @param A Input path A.
00362 /// @param B Input path B.
00363 /// @param result Set to true if stat(A) and stat(B) have the same device and
00364 ///               inode (or equivalent).
00365 /// @returns errc::success if result has been successfully set, otherwise a
00366 ///          platform specific error_code.
00367 error_code equivalent(const Twine &A, const Twine &B, bool &result);
00368 
00369 /// @brief Simpler version of equivalent for clients that don't need to
00370 ///        differentiate between an error and false.
00371 inline bool equivalent(const Twine &A, const Twine &B) {
00372   bool result;
00373   return !equivalent(A, B, result) && result;
00374 }
00375 
00376 /// @brief Get file size.
00377 ///
00378 /// @param path Input path.
00379 /// @param result Set to the size of the file in \a path.
00380 /// @returns errc::success if result has been successfully set, otherwise a
00381 ///          platform specific error_code.
00382 error_code file_size(const Twine &path, uint64_t &result);
00383 
00384 /// @brief Does status represent a directory?
00385 ///
00386 /// @param status A file_status previously returned from status.
00387 /// @returns status.type() == file_type::directory_file.
00388 bool is_directory(file_status status);
00389 
00390 /// @brief Is path a directory?
00391 ///
00392 /// @param path Input path.
00393 /// @param result Set to true if \a path is a directory, false if it is not.
00394 ///               Undefined otherwise.
00395 /// @returns errc::success if result has been successfully set, otherwise a
00396 ///          platform specific error_code.
00397 error_code is_directory(const Twine &path, bool &result);
00398 
00399 /// @brief Does status represent a regular file?
00400 ///
00401 /// @param status A file_status previously returned from status.
00402 /// @returns status_known(status) && status.type() == file_type::regular_file.
00403 bool is_regular_file(file_status status);
00404 
00405 /// @brief Is path a regular file?
00406 ///
00407 /// @param path Input path.
00408 /// @param result Set to true if \a path is a regular file, false if it is not.
00409 ///               Undefined otherwise.
00410 /// @returns errc::success if result has been successfully set, otherwise a
00411 ///          platform specific error_code.
00412 error_code is_regular_file(const Twine &path, bool &result);
00413 
00414 /// @brief Does this status represent something that exists but is not a
00415 ///        directory, regular file, or symlink?
00416 ///
00417 /// @param status A file_status previously returned from status.
00418 /// @returns exists(s) && !is_regular_file(s) && !is_directory(s) &&
00419 ///          !is_symlink(s)
00420 bool is_other(file_status status);
00421 
00422 /// @brief Is path something that exists but is not a directory,
00423 ///        regular file, or symlink?
00424 ///
00425 /// @param path Input path.
00426 /// @param result Set to true if \a path exists, but is not a directory, regular
00427 ///               file, or a symlink, false if it does not. Undefined otherwise.
00428 /// @returns errc::success if result has been successfully set, otherwise a
00429 ///          platform specific error_code.
00430 error_code is_other(const Twine &path, bool &result);
00431 
00432 /// @brief Does status represent a symlink?
00433 ///
00434 /// @param status A file_status previously returned from stat.
00435 /// @returns status.type() == symlink_file.
00436 bool is_symlink(file_status status);
00437 
00438 /// @brief Is path a symlink?
00439 ///
00440 /// @param path Input path.
00441 /// @param result Set to true if \a path is a symlink, false if it is not.
00442 ///               Undefined otherwise.
00443 /// @returns errc::success if result has been successfully set, otherwise a
00444 ///          platform specific error_code.
00445 error_code is_symlink(const Twine &path, bool &result);
00446 
00447 /// @brief Get file status as if by POSIX stat().
00448 ///
00449 /// @param path Input path.
00450 /// @param result Set to the file status.
00451 /// @returns errc::success if result has been successfully set, otherwise a
00452 ///          platform specific error_code.
00453 error_code status(const Twine &path, file_status &result);
00454 
00455 /// @brief Modifies permission bits on a file
00456 ///
00457 /// @param path Input path.
00458 /// @returns errc::success if permissions have been changed, otherwise a
00459 ///          platform specific error_code.
00460 error_code permissions(const Twine &path, perms prms);
00461 
00462 /// @brief Is status available?
00463 ///
00464 /// @param s Input file status.
00465 /// @returns True if status() != status_error.
00466 bool status_known(file_status s);
00467 
00468 /// @brief Is status available?
00469 ///
00470 /// @param path Input path.
00471 /// @param result Set to true if status() != status_error.
00472 /// @returns errc::success if result has been successfully set, otherwise a
00473 ///          platform specific error_code.
00474 error_code status_known(const Twine &path, bool &result);
00475 
00476 /// @brief Generate a unique path and open it as a file.
00477 ///
00478 /// Generates a unique path suitable for a temporary file and then opens it as a
00479 /// file. The name is based on \a model with '%' replaced by a random char in
00480 /// [0-9a-f]. If \a model is not an absolute path, a suitable temporary
00481 /// directory will be prepended.
00482 ///
00483 /// This is an atomic operation. Either the file is created and opened, or the
00484 /// file system is left untouched.
00485 ///
00486 /// clang-%%-%%-%%-%%-%%.s => /tmp/clang-a0-b1-c2-d3-e4.s
00487 ///
00488 /// @param model Name to base unique path off of.
00489 /// @param result_fd Set to the opened file's file descriptor.
00490 /// @param result_path Set to the opened file's absolute path.
00491 /// @param makeAbsolute If true and \a model is not an absolute path, a temp
00492 ///        directory will be prepended.
00493 /// @returns errc::success if result_{fd,path} have been successfully set,
00494 ///          otherwise a platform specific error_code.
00495 error_code unique_file(const Twine &model, int &result_fd,
00496                        SmallVectorImpl<char> &result_path,
00497                        bool makeAbsolute = true, unsigned mode = 0600);
00498 
00499 /// @brief Canonicalize path.
00500 ///
00501 /// Sets result to the file system's idea of what path is. The result is always
00502 /// absolute and has the same capitalization as the file system.
00503 ///
00504 /// @param path Input path.
00505 /// @param result Set to the canonicalized version of \a path.
00506 /// @returns errc::success if result has been successfully set, otherwise a
00507 ///          platform specific error_code.
00508 error_code canonicalize(const Twine &path, SmallVectorImpl<char> &result);
00509 
00510 /// @brief Are \a path's first bytes \a magic?
00511 ///
00512 /// @param path Input path.
00513 /// @param magic Byte sequence to compare \a path's first len(magic) bytes to.
00514 /// @returns errc::success if result has been successfully set, otherwise a
00515 ///          platform specific error_code.
00516 error_code has_magic(const Twine &path, const Twine &magic, bool &result);
00517 
00518 /// @brief Get \a path's first \a len bytes.
00519 ///
00520 /// @param path Input path.
00521 /// @param len Number of magic bytes to get.
00522 /// @param result Set to the first \a len bytes in the file pointed to by
00523 ///               \a path. Or the entire file if file_size(path) < len, in which
00524 ///               case result.size() returns the size of the file.
00525 /// @returns errc::success if result has been successfully set,
00526 ///          errc::value_too_large if len is larger then the file pointed to by
00527 ///          \a path, otherwise a platform specific error_code.
00528 error_code get_magic(const Twine &path, uint32_t len,
00529                      SmallVectorImpl<char> &result);
00530 
00531 /// @brief Identify the type of a binary file based on how magical it is.
00532 file_magic identify_magic(StringRef magic);
00533 
00534 /// @brief Get and identify \a path's type based on its content.
00535 ///
00536 /// @param path Input path.
00537 /// @param result Set to the type of file, or LLVMFileType::Unknown_FileType.
00538 /// @returns errc::success if result has been successfully set, otherwise a
00539 ///          platform specific error_code.
00540 error_code identify_magic(const Twine &path, file_magic &result);
00541 
00542 /// @brief Get library paths the system linker uses.
00543 ///
00544 /// @param result Set to the list of system library paths.
00545 /// @returns errc::success if result has been successfully set, otherwise a
00546 ///          platform specific error_code.
00547 error_code GetSystemLibraryPaths(SmallVectorImpl<std::string> &result);
00548 
00549 /// @brief Get bitcode library paths the system linker uses
00550 ///        + LLVM_LIB_SEARCH_PATH + LLVM_LIBDIR.
00551 ///
00552 /// @param result Set to the list of bitcode library paths.
00553 /// @returns errc::success if result has been successfully set, otherwise a
00554 ///          platform specific error_code.
00555 error_code GetBitcodeLibraryPaths(SmallVectorImpl<std::string> &result);
00556 
00557 /// @brief Find a library.
00558 ///
00559 /// Find the path to a library using its short name. Use the system
00560 /// dependent library paths to locate the library.
00561 ///
00562 /// c => /usr/lib/libc.so
00563 ///
00564 /// @param short_name Library name one would give to the system linker.
00565 /// @param result Set to the absolute path \a short_name represents.
00566 /// @returns errc::success if result has been successfully set, otherwise a
00567 ///          platform specific error_code.
00568 error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
00569 
00570 /// @brief Get absolute path of main executable.
00571 ///
00572 /// @param argv0 The program name as it was spelled on the command line.
00573 /// @param MainAddr Address of some symbol in the executable (not in a library).
00574 /// @param result Set to the absolute path of the current executable.
00575 /// @returns errc::success if result has been successfully set, otherwise a
00576 ///          platform specific error_code.
00577 error_code GetMainExecutable(const char *argv0, void *MainAddr,
00578                              SmallVectorImpl<char> &result);
00579 
00580 /// This class represents a memory mapped file. It is based on
00581 /// boost::iostreams::mapped_file.
00582 class mapped_file_region {
00583   mapped_file_region() LLVM_DELETED_FUNCTION;
00584   mapped_file_region(mapped_file_region&) LLVM_DELETED_FUNCTION;
00585   mapped_file_region &operator =(mapped_file_region&) LLVM_DELETED_FUNCTION;
00586 
00587 public:
00588   enum mapmode {
00589     readonly, ///< May only access map via const_data as read only.
00590     readwrite, ///< May access map via data and modify it. Written to path.
00591     priv ///< May modify via data, but changes are lost on destruction.
00592   };
00593 
00594 private:
00595   /// Platform specific mapping state.
00596   mapmode Mode;
00597   uint64_t Size;
00598   void *Mapping;
00599 #ifdef LLVM_ON_WIN32
00600   int FileDescriptor;
00601   void *FileHandle;
00602   void *FileMappingHandle;
00603 #endif
00604 
00605   error_code init(int FD, bool CloseFD, uint64_t Offset);
00606 
00607 public:
00608   typedef char char_type;
00609 
00610 #if LLVM_HAS_RVALUE_REFERENCES
00611   mapped_file_region(mapped_file_region&&);
00612   mapped_file_region &operator =(mapped_file_region&&);
00613 #endif
00614 
00615   /// Construct a mapped_file_region at \a path starting at \a offset of length
00616   /// \a length and with access \a mode.
00617   ///
00618   /// \param path Path to the file to map. If it does not exist it will be
00619   ///             created.
00620   /// \param mode How to map the memory.
00621   /// \param length Number of bytes to map in starting at \a offset. If the file
00622   ///               is shorter than this, it will be extended. If \a length is
00623   ///               0, the entire file will be mapped.
00624   /// \param offset Byte offset from the beginning of the file where the map
00625   ///               should begin. Must be a multiple of
00626   ///               mapped_file_region::alignment().
00627   /// \param ec This is set to errc::success if the map was constructed
00628   ///           sucessfully. Otherwise it is set to a platform dependent error.
00629   mapped_file_region(const Twine &path,
00630                      mapmode mode,
00631                      uint64_t length,
00632                      uint64_t offset,
00633                      error_code &ec);
00634 
00635   /// \param fd An open file descriptor to map. mapped_file_region takes
00636   ///   ownership if closefd is true. It must have been opended in the correct
00637   ///   mode.
00638   mapped_file_region(int fd,
00639                      bool closefd,
00640                      mapmode mode,
00641                      uint64_t length,
00642                      uint64_t offset,
00643                      error_code &ec);
00644 
00645   ~mapped_file_region();
00646 
00647   mapmode flags() const;
00648   uint64_t size() const;
00649   char *data() const;
00650 
00651   /// Get a const view of the data. Modifying this memory has undefined
00652   /// behaivor.
00653   const char *const_data() const;
00654 
00655   /// \returns The minimum alignment offset must be.
00656   static int alignment();
00657 };
00658 
00659 /// @brief Memory maps the contents of a file
00660 ///
00661 /// @param path Path to file to map.
00662 /// @param file_offset Byte offset in file where mapping should begin.
00663 /// @param size Byte length of range of the file to map.
00664 /// @param map_writable If true, the file will be mapped in r/w such
00665 ///        that changes to the mapped buffer will be flushed back
00666 ///        to the file.  If false, the file will be mapped read-only
00667 ///        and the buffer will be read-only.
00668 /// @param result Set to the start address of the mapped buffer.
00669 /// @returns errc::success if result has been successfully set, otherwise a
00670 ///          platform specific error_code.
00671 error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,  
00672                           bool map_writable, void *&result);
00673 
00674 
00675 /// @brief Memory unmaps the contents of a file
00676 ///
00677 /// @param base Pointer to the start of the buffer.
00678 /// @param size Byte length of the range to unmmap.
00679 /// @returns errc::success if result has been successfully set, otherwise a
00680 ///          platform specific error_code.
00681 error_code unmap_file_pages(void *base, size_t size);
00682 
00683 
00684 
00685 /// @}
00686 /// @name Iterators
00687 /// @{
00688 
00689 /// directory_entry - A single entry in a directory. Caches the status either
00690 /// from the result of the iteration syscall, or the first time status is
00691 /// called.
00692 class directory_entry {
00693   std::string Path;
00694   mutable file_status Status;
00695 
00696 public:
00697   explicit directory_entry(const Twine &path, file_status st = file_status())
00698     : Path(path.str())
00699     , Status(st) {}
00700 
00701   directory_entry() {}
00702 
00703   void assign(const Twine &path, file_status st = file_status()) {
00704     Path = path.str();
00705     Status = st;
00706   }
00707 
00708   void replace_filename(const Twine &filename, file_status st = file_status());
00709 
00710   const std::string &path() const { return Path; }
00711   error_code status(file_status &result) const;
00712 
00713   bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; }
00714   bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); }
00715   bool operator< (const directory_entry& rhs) const;
00716   bool operator<=(const directory_entry& rhs) const;
00717   bool operator> (const directory_entry& rhs) const;
00718   bool operator>=(const directory_entry& rhs) const;
00719 };
00720 
00721 namespace detail {
00722   struct DirIterState;
00723 
00724   error_code directory_iterator_construct(DirIterState&, StringRef);
00725   error_code directory_iterator_increment(DirIterState&);
00726   error_code directory_iterator_destruct(DirIterState&);
00727 
00728   /// DirIterState - Keeps state for the directory_iterator. It is reference
00729   /// counted in order to preserve InputIterator semantics on copy.
00730   struct DirIterState : public RefCountedBase<DirIterState> {
00731     DirIterState()
00732       : IterationHandle(0) {}
00733 
00734     ~DirIterState() {
00735       directory_iterator_destruct(*this);
00736     }
00737 
00738     intptr_t IterationHandle;
00739     directory_entry CurrentEntry;
00740   };
00741 }
00742 
00743 /// directory_iterator - Iterates through the entries in path. There is no
00744 /// operator++ because we need an error_code. If it's really needed we can make
00745 /// it call report_fatal_error on error.
00746 class directory_iterator {
00747   IntrusiveRefCntPtr<detail::DirIterState> State;
00748 
00749 public:
00750   explicit directory_iterator(const Twine &path, error_code &ec) {
00751     State = new detail::DirIterState;
00752     SmallString<128> path_storage;
00753     ec = detail::directory_iterator_construct(*State,
00754             path.toStringRef(path_storage));
00755   }
00756 
00757   explicit directory_iterator(const directory_entry &de, error_code &ec) {
00758     State = new detail::DirIterState;
00759     ec = detail::directory_iterator_construct(*State, de.path());
00760   }
00761 
00762   /// Construct end iterator.
00763   directory_iterator() : State(new detail::DirIterState) {}
00764 
00765   // No operator++ because we need error_code.
00766   directory_iterator &increment(error_code &ec) {
00767     ec = directory_iterator_increment(*State);
00768     return *this;
00769   }
00770 
00771   const directory_entry &operator*() const { return State->CurrentEntry; }
00772   const directory_entry *operator->() const { return &State->CurrentEntry; }
00773 
00774   bool operator==(const directory_iterator &RHS) const {
00775     return State->CurrentEntry == RHS.State->CurrentEntry;
00776   }
00777 
00778   bool operator!=(const directory_iterator &RHS) const {
00779     return !(*this == RHS);
00780   }
00781   // Other members as required by
00782   // C++ Std, 24.1.1 Input iterators [input.iterators]
00783 };
00784 
00785 namespace detail {
00786   /// RecDirIterState - Keeps state for the recursive_directory_iterator. It is
00787   /// reference counted in order to preserve InputIterator semantics on copy.
00788   struct RecDirIterState : public RefCountedBase<RecDirIterState> {
00789     RecDirIterState()
00790       : Level(0)
00791       , HasNoPushRequest(false) {}
00792 
00793     std::stack<directory_iterator, std::vector<directory_iterator> > Stack;
00794     uint16_t Level;
00795     bool HasNoPushRequest;
00796   };
00797 }
00798 
00799 /// recursive_directory_iterator - Same as directory_iterator except for it
00800 /// recurses down into child directories.
00801 class recursive_directory_iterator {
00802   IntrusiveRefCntPtr<detail::RecDirIterState> State;
00803 
00804 public:
00805   recursive_directory_iterator() {}
00806   explicit recursive_directory_iterator(const Twine &path, error_code &ec)
00807     : State(new detail::RecDirIterState) {
00808     State->Stack.push(directory_iterator(path, ec));
00809     if (State->Stack.top() == directory_iterator())
00810       State.reset();
00811   }
00812   // No operator++ because we need error_code.
00813   recursive_directory_iterator &increment(error_code &ec) {
00814     static const directory_iterator end_itr;
00815 
00816     if (State->HasNoPushRequest)
00817       State->HasNoPushRequest = false;
00818     else {
00819       file_status st;
00820       if ((ec = State->Stack.top()->status(st))) return *this;
00821       if (is_directory(st)) {
00822         State->Stack.push(directory_iterator(*State->Stack.top(), ec));
00823         if (ec) return *this;
00824         if (State->Stack.top() != end_itr) {
00825           ++State->Level;
00826           return *this;
00827         }
00828         State->Stack.pop();
00829       }
00830     }
00831 
00832     while (!State->Stack.empty()
00833            && State->Stack.top().increment(ec) == end_itr) {
00834       State->Stack.pop();
00835       --State->Level;
00836     }
00837 
00838     // Check if we are done. If so, create an end iterator.
00839     if (State->Stack.empty())
00840       State.reset();
00841 
00842     return *this;
00843   }
00844 
00845   const directory_entry &operator*() const { return *State->Stack.top(); }
00846   const directory_entry *operator->() const { return &*State->Stack.top(); }
00847 
00848   // observers
00849   /// Gets the current level. Starting path is at level 0.
00850   int level() const { return State->Level; }
00851 
00852   /// Returns true if no_push has been called for this directory_entry.
00853   bool no_push_request() const { return State->HasNoPushRequest; }
00854 
00855   // modifiers
00856   /// Goes up one level if Level > 0.
00857   void pop() {
00858     assert(State && "Cannot pop and end itertor!");
00859     assert(State->Level > 0 && "Cannot pop an iterator with level < 1");
00860 
00861     static const directory_iterator end_itr;
00862     error_code ec;
00863     do {
00864       if (ec)
00865         report_fatal_error("Error incrementing directory iterator.");
00866       State->Stack.pop();
00867       --State->Level;
00868     } while (!State->Stack.empty()
00869              && State->Stack.top().increment(ec) == end_itr);
00870 
00871     // Check if we are done. If so, create an end iterator.
00872     if (State->Stack.empty())
00873       State.reset();
00874   }
00875 
00876   /// Does not go down into the current directory_entry.
00877   void no_push() { State->HasNoPushRequest = true; }
00878 
00879   bool operator==(const recursive_directory_iterator &RHS) const {
00880     return State == RHS.State;
00881   }
00882 
00883   bool operator!=(const recursive_directory_iterator &RHS) const {
00884     return !(*this == RHS);
00885   }
00886   // Other members as required by
00887   // C++ Std, 24.1.1 Input iterators [input.iterators]
00888 };
00889 
00890 /// @}
00891 
00892 } // end namespace fs
00893 } // end namespace sys
00894 } // end namespace llvm
00895 
00896 #endif