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
|
/* -*- 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 "prlink.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(MOZILLA_INTERNAL_API)
/**
* 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);
/*
* Wrappers for PR_GetLibraryName and PR_GetLibraryFilePathname.
*/
PathString GetLibraryName(pathstr_t aDirectory, const char* aLib);
PathString GetLibraryFilePathname(pathstr_t aName, PRFuncPtr aAddr);
#endif // MOZILLA_INTERNAL_API
/**
* 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(XP_UNIX)
# define MOZ_TEMP_FAILURE_RETRY(exp) \
(__extension__({ \
typeof(exp) _rc; \
do { \
_rc = (exp); \
} while (_rc == -1 && errno == EINTR); \
_rc; \
}))
#endif
} // namespace mozilla
#endif
|