1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_FileUtils_h 8 #define mozilla_FileUtils_h 9 10 #include "nscore.h" // nullptr 11 12 #if defined(XP_UNIX) 13 # include <unistd.h> 14 #elif defined(XP_WIN) 15 # include <io.h> 16 #endif 17 #include "prio.h" 18 #include "prlink.h" 19 20 #include "mozilla/Scoped.h" 21 #include "nsIFile.h" 22 #include <errno.h> 23 #include <limits.h> 24 25 namespace mozilla { 26 27 #if defined(XP_WIN) 28 typedef void* filedesc_t; 29 typedef const wchar_t* pathstr_t; 30 #else 31 typedef int filedesc_t; 32 typedef const char* pathstr_t; 33 #endif 34 35 /** 36 * ScopedCloseFD is a RAII wrapper for POSIX file descriptors 37 * 38 * Instances |close()| their fds when they go out of scope. 39 */ 40 struct ScopedCloseFDTraits { 41 typedef int type; emptyScopedCloseFDTraits42 static type empty() { return -1; } releaseScopedCloseFDTraits43 static void release(type aFd) { 44 if (aFd != -1) { 45 close(aFd); 46 } 47 } 48 }; 49 typedef Scoped<ScopedCloseFDTraits> ScopedClose; 50 51 #if defined(MOZILLA_INTERNAL_API) 52 53 /** 54 * AutoFDClose is a RAII wrapper for PRFileDesc. 55 * 56 * Instances |PR_Close| their fds when they go out of scope. 57 **/ 58 struct ScopedClosePRFDTraits { 59 typedef PRFileDesc* type; emptyScopedClosePRFDTraits60 static type empty() { return nullptr; } releaseScopedClosePRFDTraits61 static void release(type aFd) { 62 if (aFd) { 63 PR_Close(aFd); 64 } 65 } 66 }; 67 typedef Scoped<ScopedClosePRFDTraits> AutoFDClose; 68 69 /* RAII wrapper for FILE descriptors */ 70 struct ScopedCloseFileTraits { 71 typedef FILE* type; emptyScopedCloseFileTraits72 static type empty() { return nullptr; } releaseScopedCloseFileTraits73 static void release(type aFile) { 74 if (aFile) { 75 fclose(aFile); 76 } 77 } 78 }; 79 typedef Scoped<ScopedCloseFileTraits> ScopedCloseFile; 80 81 /** 82 * Fallocate efficiently and continuously allocates files via fallocate-type 83 * APIs. This is useful for avoiding fragmentation. On sucess the file be padded 84 * with zeros to grow to aLength. 85 * 86 * @param aFD file descriptor. 87 * @param aLength length of file to grow to. 88 * @return true on success. 89 */ 90 bool fallocate(PRFileDesc* aFD, int64_t aLength); 91 92 /** 93 * Use readahead to preload shared libraries into the file cache before loading. 94 * WARNING: This function should not be used without a telemetry field trial 95 * demonstrating a clear performance improvement! 96 * 97 * @param aFile nsIFile representing path to shared library 98 */ 99 void ReadAheadLib(nsIFile* aFile); 100 101 /** 102 * Use readahead to preload a file into the file cache before reading. 103 * WARNING: This function should not be used without a telemetry field trial 104 * demonstrating a clear performance improvement! 105 * 106 * @param aFile nsIFile representing path to shared library 107 * @param aOffset Offset into the file to begin preloading 108 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) 109 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will 110 * return its internal, opened file descriptor instead of closing it. 111 */ 112 void ReadAheadFile(nsIFile* aFile, const size_t aOffset = 0, 113 const size_t aCount = SIZE_MAX, 114 filedesc_t* aOutFd = nullptr); 115 116 /* 117 * Wrappers for PR_GetLibraryName and PR_GetLibraryFilePathname. 118 */ 119 PathString GetLibraryName(pathstr_t aDirectory, const char* aLib); 120 PathString GetLibraryFilePathname(pathstr_t aName, PRFuncPtr aAddr); 121 122 #endif // MOZILLA_INTERNAL_API 123 124 /** 125 * Use readahead to preload shared libraries into the file cache before loading. 126 * WARNING: This function should not be used without a telemetry field trial 127 * demonstrating a clear performance improvement! 128 * 129 * @param aFilePath path to shared library 130 */ 131 void ReadAheadLib(pathstr_t aFilePath); 132 133 /** 134 * Use readahead to preload a file into the file cache before loading. 135 * WARNING: This function should not be used without a telemetry field trial 136 * demonstrating a clear performance improvement! 137 * 138 * @param aFilePath path to shared library 139 * @param aOffset Offset into the file to begin preloading 140 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) 141 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will 142 * return its internal, opened file descriptor instead of closing it. 143 */ 144 void ReadAheadFile(pathstr_t aFilePath, const size_t aOffset = 0, 145 const size_t aCount = SIZE_MAX, 146 filedesc_t* aOutFd = nullptr); 147 148 /** 149 * Use readahead to preload a file into the file cache before reading. 150 * When this function exits, the file pointer is guaranteed to be in the same 151 * position it was in before this function was called. 152 * WARNING: This function should not be used without a telemetry field trial 153 * demonstrating a clear performance improvement! 154 * 155 * @param aFd file descriptor opened for read access 156 * (on Windows, file must be opened with FILE_FLAG_SEQUENTIAL_SCAN) 157 * @param aOffset Offset into the file to begin preloading 158 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) 159 */ 160 void ReadAhead(filedesc_t aFd, const size_t aOffset = 0, 161 const size_t aCount = SIZE_MAX); 162 163 } // namespace mozilla 164 165 #endif 166