michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_FileUtils_h michael@0: #define mozilla_FileUtils_h michael@0: michael@0: #include "nscore.h" // nullptr michael@0: michael@0: #if defined(XP_UNIX) michael@0: # include michael@0: #elif defined(XP_WIN) michael@0: # include michael@0: #endif michael@0: #include "prio.h" michael@0: michael@0: #include "mozilla/Scoped.h" michael@0: #include "nsIFile.h" michael@0: #include michael@0: #include michael@0: michael@0: namespace mozilla { michael@0: michael@0: #if defined(XP_WIN) michael@0: typedef void* filedesc_t; michael@0: typedef const wchar_t* pathstr_t; michael@0: #else michael@0: typedef int filedesc_t; michael@0: typedef const char* pathstr_t; michael@0: #endif michael@0: michael@0: /** michael@0: * ScopedCloseFD is a RAII wrapper for POSIX file descriptors michael@0: * michael@0: * Instances |close()| their fds when they go out of scope. michael@0: */ michael@0: struct ScopedCloseFDTraits michael@0: { michael@0: typedef int type; michael@0: static type empty() { return -1; } michael@0: static void release(type fd) { michael@0: if (fd != -1) { michael@0: while ((close(fd) == -1) && (errno == EINTR)) { michael@0: ; michael@0: } michael@0: } michael@0: } michael@0: }; michael@0: typedef Scoped ScopedClose; michael@0: michael@0: #if !defined(XPCOM_GLUE) michael@0: michael@0: /** michael@0: * AutoFDClose is a RAII wrapper for PRFileDesc. michael@0: * michael@0: * Instances |PR_Close| their fds when they go out of scope. michael@0: **/ michael@0: struct ScopedClosePRFDTraits michael@0: { michael@0: typedef PRFileDesc* type; michael@0: static type empty() { return nullptr; } michael@0: static void release(type fd) { michael@0: if (fd != nullptr) { michael@0: PR_Close(fd); michael@0: } michael@0: } michael@0: }; michael@0: typedef Scoped AutoFDClose; michael@0: michael@0: /* RAII wrapper for FILE descriptors */ michael@0: struct ScopedCloseFileTraits michael@0: { michael@0: typedef FILE *type; michael@0: static type empty() { return nullptr; } michael@0: static void release(type f) { michael@0: if (f) { michael@0: fclose(f); michael@0: } michael@0: } michael@0: }; michael@0: typedef Scoped ScopedCloseFile; michael@0: michael@0: /** michael@0: * Fallocate efficiently and continuously allocates files via fallocate-type APIs. michael@0: * This is useful for avoiding fragmentation. michael@0: * On sucess the file be padded with zeros to grow to aLength. michael@0: * michael@0: * @param aFD file descriptor. michael@0: * @param aLength length of file to grow to. michael@0: * @return true on success. michael@0: */ michael@0: NS_COM_GLUE bool fallocate(PRFileDesc *aFD, int64_t aLength); michael@0: michael@0: /** michael@0: * Use readahead to preload shared libraries into the file cache before loading. michael@0: * WARNING: This function should not be used without a telemetry field trial michael@0: * demonstrating a clear performance improvement! michael@0: * michael@0: * @param aFile nsIFile representing path to shared library michael@0: */ michael@0: NS_COM_GLUE void ReadAheadLib(nsIFile* aFile); michael@0: michael@0: /** michael@0: * Use readahead to preload a file into the file cache before reading. michael@0: * WARNING: This function should not be used without a telemetry field trial michael@0: * demonstrating a clear performance improvement! michael@0: * michael@0: * @param aFile nsIFile representing path to shared library michael@0: * @param aOffset Offset into the file to begin preloading michael@0: * @param aCount Number of bytes to preload (SIZE_MAX implies file size) michael@0: * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will michael@0: * return its internal, opened file descriptor instead of closing it. michael@0: */ michael@0: NS_COM_GLUE void ReadAheadFile(nsIFile* aFile, const size_t aOffset = 0, michael@0: const size_t aCount = SIZE_MAX, michael@0: filedesc_t* aOutFd = nullptr); michael@0: michael@0: #endif // !defined(XPCOM_GLUE) michael@0: michael@0: /** michael@0: * Use readahead to preload shared libraries into the file cache before loading. michael@0: * WARNING: This function should not be used without a telemetry field trial michael@0: * demonstrating a clear performance improvement! michael@0: * michael@0: * @param aFilePath path to shared library michael@0: */ michael@0: NS_COM_GLUE void ReadAheadLib(pathstr_t aFilePath); michael@0: michael@0: /** michael@0: * Use readahead to preload a file into the file cache before loading. michael@0: * WARNING: This function should not be used without a telemetry field trial michael@0: * demonstrating a clear performance improvement! michael@0: * michael@0: * @param aFilePath path to shared library michael@0: * @param aOffset Offset into the file to begin preloading michael@0: * @param aCount Number of bytes to preload (SIZE_MAX implies file size) michael@0: * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will michael@0: * return its internal, opened file descriptor instead of closing it. michael@0: */ michael@0: NS_COM_GLUE void ReadAheadFile(pathstr_t aFilePath, const size_t aOffset = 0, michael@0: const size_t aCount = SIZE_MAX, michael@0: filedesc_t* aOutFd = nullptr); michael@0: michael@0: /** michael@0: * Use readahead to preload a file into the file cache before reading. michael@0: * When this function exits, the file pointer is guaranteed to be in the same michael@0: * position it was in before this function was called. michael@0: * WARNING: This function should not be used without a telemetry field trial michael@0: * demonstrating a clear performance improvement! michael@0: * michael@0: * @param aFd file descriptor opened for read access michael@0: * (on Windows, file must be opened with FILE_FLAG_SEQUENTIAL_SCAN) michael@0: * @param aOffset Offset into the file to begin preloading michael@0: * @param aCount Number of bytes to preload (SIZE_MAX implies file size) michael@0: */ michael@0: NS_COM_GLUE void ReadAhead(filedesc_t aFd, const size_t aOffset = 0, michael@0: const size_t aCount = SIZE_MAX); michael@0: michael@0: michael@0: /* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat. michael@0: Also define it in debug builds, so that unit tests for it can be written michael@0: and run in non-GONK builds. */ michael@0: #if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX) michael@0: michael@0: #ifndef ReadSysFile_PRESENT michael@0: #define ReadSysFile_PRESENT michael@0: #endif /* ReadSysFile_PRESENT */ michael@0: michael@0: #define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \ michael@0: typeof (exp) _rc; \ michael@0: do { \ michael@0: _rc = (exp); \ michael@0: } while (_rc == -1 && errno == EINTR); \ michael@0: _rc; \ michael@0: })) michael@0: michael@0: /** michael@0: * Read the contents of a file. michael@0: * This function is intended for reading a single-lined text files from michael@0: * /sys/. If the file ends with a newline ('\n') then it will be discarded. michael@0: * The output buffer will always be '\0'-terminated on successful completion. michael@0: * If aBufSize == 0, then this function will return true if the file exists michael@0: * and is readable (it will not attempt to read anything from it). michael@0: * On failure the contents of aBuf after this call will be undefined and the michael@0: * value of the global variable errno will be set accordingly. michael@0: * @return true on success, notice that less than requested bytes could have michael@0: * been read if the file was smaller michael@0: */ michael@0: bool michael@0: ReadSysFile( michael@0: const char* aFilename, michael@0: char* aBuf, michael@0: size_t aBufSize); michael@0: michael@0: /** michael@0: * Parse the contents of a file, assuming it contains a decimal integer. michael@0: * @return true on success michael@0: */ michael@0: bool michael@0: ReadSysFile( michael@0: const char* aFilename, michael@0: int* aVal); michael@0: michael@0: /** michael@0: * Parse the contents of a file, assuming it contains a boolean value michael@0: * (either 0 or 1). michael@0: * @return true on success michael@0: */ michael@0: bool michael@0: ReadSysFile( michael@0: const char* aFilename, michael@0: bool* aVal); michael@0: michael@0: #endif /* (MOZ_WIDGET_GONK || DEBUG) && XP_UNIX */ michael@0: michael@0: } // namespace mozilla michael@0: #endif