DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (dcc6d7a0dc00)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_FileUtils_h
#define mozilla_FileUtils_h

#include "nscore.h" // nullptr

#if defined(XP_UNIX)
# include <unistd.h>
#elif defined(XP_WIN)
# include <io.h>
#endif
#include "prio.h"

#include "mozilla/Scoped.h"
#include "nsIFile.h"
#include <errno.h>
#include <limits.h>

namespace mozilla {

#if defined(XP_WIN)
typedef void* filedesc_t;
typedef const wchar_t* pathstr_t;
#else
typedef int filedesc_t;
typedef const char* pathstr_t;
#endif

/**
 * ScopedCloseFD is a RAII wrapper for POSIX file descriptors
 *
 * Instances |close()| their fds when they go out of scope.
 */
struct ScopedCloseFDTraits
{
  typedef int type;
  static type empty() { return -1; }
  static void release(type aFd)
  {
    if (aFd != -1) {
      while (close(aFd) == -1 && errno == EINTR) {
      }
    }
  }
};
typedef Scoped<ScopedCloseFDTraits> ScopedClose;

#if !defined(XPCOM_GLUE)

/**
 * AutoFDClose is a RAII wrapper for PRFileDesc.
 *
 * Instances |PR_Close| their fds when they go out of scope.
 **/
struct ScopedClosePRFDTraits
{
  typedef PRFileDesc* type;
  static type empty() { return nullptr; }
  static void release(type aFd)
  {
    if (aFd) {
      PR_Close(aFd);
    }
  }
};
typedef Scoped<ScopedClosePRFDTraits> AutoFDClose;

/* RAII wrapper for FILE descriptors */
struct ScopedCloseFileTraits
{
  typedef FILE* type;
  static type empty() { return nullptr; }
  static void release(type aFile)
  {
    if (aFile) {
      fclose(aFile);
    }
  }
};
typedef Scoped<ScopedCloseFileTraits> ScopedCloseFile;

/**
 * Fallocate efficiently and continuously allocates files via fallocate-type APIs.
 * This is useful for avoiding fragmentation.
 * On sucess the file be padded with zeros to grow to aLength.
 *
 * @param aFD file descriptor.
 * @param aLength length of file to grow to.
 * @return true on success.
 */
bool fallocate(PRFileDesc* aFD, int64_t aLength);

/**
 * Use readahead to preload shared libraries into the file cache before loading.
 * WARNING: This function should not be used without a telemetry field trial
 *          demonstrating a clear performance improvement!
 *
 * @param aFile nsIFile representing path to shared library
 */
void ReadAheadLib(nsIFile* aFile);

/**
 * Use readahead to preload a file into the file cache before reading.
 * WARNING: This function should not be used without a telemetry field trial
 *          demonstrating a clear performance improvement!
 *
 * @param aFile nsIFile representing path to shared library
 * @param aOffset Offset into the file to begin preloading
 * @param aCount Number of bytes to preload (SIZE_MAX implies file size)
 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will
 *        return its internal, opened file descriptor instead of closing it.
 */
void ReadAheadFile(nsIFile* aFile, const size_t aOffset = 0,
                   const size_t aCount = SIZE_MAX,
                   filedesc_t* aOutFd = nullptr);

#endif // !defined(XPCOM_GLUE)

/**
 * Use readahead to preload shared libraries into the file cache before loading.
 * WARNING: This function should not be used without a telemetry field trial
 *          demonstrating a clear performance improvement!
 *
 * @param aFilePath path to shared library
 */
void ReadAheadLib(pathstr_t aFilePath);

/**
 * Use readahead to preload a file into the file cache before loading.
 * WARNING: This function should not be used without a telemetry field trial
 *          demonstrating a clear performance improvement!
 *
 * @param aFilePath path to shared library
 * @param aOffset Offset into the file to begin preloading
 * @param aCount Number of bytes to preload (SIZE_MAX implies file size)
 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will
 *        return its internal, opened file descriptor instead of closing it.
 */
void ReadAheadFile(pathstr_t aFilePath, const size_t aOffset = 0,
                   const size_t aCount = SIZE_MAX,
                   filedesc_t* aOutFd = nullptr);

/**
 * Use readahead to preload a file into the file cache before reading.
 * When this function exits, the file pointer is guaranteed to be in the same
 * position it was in before this function was called.
 * WARNING: This function should not be used without a telemetry field trial
 *          demonstrating a clear performance improvement!
 *
 * @param aFd file descriptor opened for read access
 * (on Windows, file must be opened with FILE_FLAG_SEQUENTIAL_SCAN)
 * @param aOffset Offset into the file to begin preloading
 * @param aCount Number of bytes to preload (SIZE_MAX implies file size)
 */
void ReadAhead(filedesc_t aFd, const size_t aOffset = 0,
               const size_t aCount = SIZE_MAX);


#if defined(MOZ_WIDGET_GONK) || defined(XP_UNIX)
#define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
  typeof (exp) _rc; \
  do { \
    _rc = (exp); \
  } while (_rc == -1 && errno == EINTR); \
  _rc; \
}))
#endif

/* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat.
Also define it in debug builds, so that unit tests for it can be written
and run in non-GONK builds. */
#if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX)

#ifndef ReadSysFile_PRESENT
#define ReadSysFile_PRESENT
#endif /* ReadSysFile_PRESENT */

/**
 * Read the contents of a file.
 * This function is intended for reading a single-lined text files from
 * /sys/. If the file ends with a newline ('\n') then it will be discarded.
 * The output buffer will always be '\0'-terminated on successful completion.
 * If aBufSize == 0, then this function will return true if the file exists
 * and is readable (it will not attempt to read anything from it).
 * On failure the contents of aBuf after this call will be undefined and the
 * value of the global variable errno will be set accordingly.
 * @return true on success, notice that less than requested bytes could have
 * been read if the file was smaller
 */
bool ReadSysFile(const char* aFilename, char* aBuf, size_t aBufSize);

/**
 * Parse the contents of a file, assuming it contains a decimal integer.
 * @return true on success
 */
bool ReadSysFile(const char* aFilename, int* aVal);

/**
 * Parse the contents of a file, assuming it contains a boolean value
 * (either 0 or 1).
 * @return true on success
 */
bool ReadSysFile(const char* aFilename, bool* aVal);

#endif /* (MOZ_WIDGET_GONK || DEBUG) && XP_UNIX */

} // namespace mozilla

#endif