|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef mozilla_FileUtils_h |
|
7 #define mozilla_FileUtils_h |
|
8 |
|
9 #include "nscore.h" // nullptr |
|
10 |
|
11 #if defined(XP_UNIX) |
|
12 # include <unistd.h> |
|
13 #elif defined(XP_WIN) |
|
14 # include <io.h> |
|
15 #endif |
|
16 #include "prio.h" |
|
17 |
|
18 #include "mozilla/Scoped.h" |
|
19 #include "nsIFile.h" |
|
20 #include <errno.h> |
|
21 #include <limits.h> |
|
22 |
|
23 namespace mozilla { |
|
24 |
|
25 #if defined(XP_WIN) |
|
26 typedef void* filedesc_t; |
|
27 typedef const wchar_t* pathstr_t; |
|
28 #else |
|
29 typedef int filedesc_t; |
|
30 typedef const char* pathstr_t; |
|
31 #endif |
|
32 |
|
33 /** |
|
34 * ScopedCloseFD is a RAII wrapper for POSIX file descriptors |
|
35 * |
|
36 * Instances |close()| their fds when they go out of scope. |
|
37 */ |
|
38 struct ScopedCloseFDTraits |
|
39 { |
|
40 typedef int type; |
|
41 static type empty() { return -1; } |
|
42 static void release(type fd) { |
|
43 if (fd != -1) { |
|
44 while ((close(fd) == -1) && (errno == EINTR)) { |
|
45 ; |
|
46 } |
|
47 } |
|
48 } |
|
49 }; |
|
50 typedef Scoped<ScopedCloseFDTraits> ScopedClose; |
|
51 |
|
52 #if !defined(XPCOM_GLUE) |
|
53 |
|
54 /** |
|
55 * AutoFDClose is a RAII wrapper for PRFileDesc. |
|
56 * |
|
57 * Instances |PR_Close| their fds when they go out of scope. |
|
58 **/ |
|
59 struct ScopedClosePRFDTraits |
|
60 { |
|
61 typedef PRFileDesc* type; |
|
62 static type empty() { return nullptr; } |
|
63 static void release(type fd) { |
|
64 if (fd != nullptr) { |
|
65 PR_Close(fd); |
|
66 } |
|
67 } |
|
68 }; |
|
69 typedef Scoped<ScopedClosePRFDTraits> AutoFDClose; |
|
70 |
|
71 /* RAII wrapper for FILE descriptors */ |
|
72 struct ScopedCloseFileTraits |
|
73 { |
|
74 typedef FILE *type; |
|
75 static type empty() { return nullptr; } |
|
76 static void release(type f) { |
|
77 if (f) { |
|
78 fclose(f); |
|
79 } |
|
80 } |
|
81 }; |
|
82 typedef Scoped<ScopedCloseFileTraits> ScopedCloseFile; |
|
83 |
|
84 /** |
|
85 * Fallocate efficiently and continuously allocates files via fallocate-type APIs. |
|
86 * This is useful for avoiding fragmentation. |
|
87 * On sucess the file be padded with zeros to grow to aLength. |
|
88 * |
|
89 * @param aFD file descriptor. |
|
90 * @param aLength length of file to grow to. |
|
91 * @return true on success. |
|
92 */ |
|
93 NS_COM_GLUE bool fallocate(PRFileDesc *aFD, int64_t aLength); |
|
94 |
|
95 /** |
|
96 * Use readahead to preload shared libraries into the file cache before loading. |
|
97 * WARNING: This function should not be used without a telemetry field trial |
|
98 * demonstrating a clear performance improvement! |
|
99 * |
|
100 * @param aFile nsIFile representing path to shared library |
|
101 */ |
|
102 NS_COM_GLUE void ReadAheadLib(nsIFile* aFile); |
|
103 |
|
104 /** |
|
105 * Use readahead to preload a file into the file cache before reading. |
|
106 * WARNING: This function should not be used without a telemetry field trial |
|
107 * demonstrating a clear performance improvement! |
|
108 * |
|
109 * @param aFile nsIFile representing path to shared library |
|
110 * @param aOffset Offset into the file to begin preloading |
|
111 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) |
|
112 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will |
|
113 * return its internal, opened file descriptor instead of closing it. |
|
114 */ |
|
115 NS_COM_GLUE void ReadAheadFile(nsIFile* aFile, const size_t aOffset = 0, |
|
116 const size_t aCount = SIZE_MAX, |
|
117 filedesc_t* aOutFd = nullptr); |
|
118 |
|
119 #endif // !defined(XPCOM_GLUE) |
|
120 |
|
121 /** |
|
122 * Use readahead to preload shared libraries into the file cache before loading. |
|
123 * WARNING: This function should not be used without a telemetry field trial |
|
124 * demonstrating a clear performance improvement! |
|
125 * |
|
126 * @param aFilePath path to shared library |
|
127 */ |
|
128 NS_COM_GLUE void ReadAheadLib(pathstr_t aFilePath); |
|
129 |
|
130 /** |
|
131 * Use readahead to preload a file into the file cache before loading. |
|
132 * WARNING: This function should not be used without a telemetry field trial |
|
133 * demonstrating a clear performance improvement! |
|
134 * |
|
135 * @param aFilePath path to shared library |
|
136 * @param aOffset Offset into the file to begin preloading |
|
137 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) |
|
138 * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will |
|
139 * return its internal, opened file descriptor instead of closing it. |
|
140 */ |
|
141 NS_COM_GLUE void ReadAheadFile(pathstr_t aFilePath, const size_t aOffset = 0, |
|
142 const size_t aCount = SIZE_MAX, |
|
143 filedesc_t* aOutFd = nullptr); |
|
144 |
|
145 /** |
|
146 * Use readahead to preload a file into the file cache before reading. |
|
147 * When this function exits, the file pointer is guaranteed to be in the same |
|
148 * position it was in before this function was called. |
|
149 * WARNING: This function should not be used without a telemetry field trial |
|
150 * demonstrating a clear performance improvement! |
|
151 * |
|
152 * @param aFd file descriptor opened for read access |
|
153 * (on Windows, file must be opened with FILE_FLAG_SEQUENTIAL_SCAN) |
|
154 * @param aOffset Offset into the file to begin preloading |
|
155 * @param aCount Number of bytes to preload (SIZE_MAX implies file size) |
|
156 */ |
|
157 NS_COM_GLUE void ReadAhead(filedesc_t aFd, const size_t aOffset = 0, |
|
158 const size_t aCount = SIZE_MAX); |
|
159 |
|
160 |
|
161 /* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat. |
|
162 Also define it in debug builds, so that unit tests for it can be written |
|
163 and run in non-GONK builds. */ |
|
164 #if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX) |
|
165 |
|
166 #ifndef ReadSysFile_PRESENT |
|
167 #define ReadSysFile_PRESENT |
|
168 #endif /* ReadSysFile_PRESENT */ |
|
169 |
|
170 #define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \ |
|
171 typeof (exp) _rc; \ |
|
172 do { \ |
|
173 _rc = (exp); \ |
|
174 } while (_rc == -1 && errno == EINTR); \ |
|
175 _rc; \ |
|
176 })) |
|
177 |
|
178 /** |
|
179 * Read the contents of a file. |
|
180 * This function is intended for reading a single-lined text files from |
|
181 * /sys/. If the file ends with a newline ('\n') then it will be discarded. |
|
182 * The output buffer will always be '\0'-terminated on successful completion. |
|
183 * If aBufSize == 0, then this function will return true if the file exists |
|
184 * and is readable (it will not attempt to read anything from it). |
|
185 * On failure the contents of aBuf after this call will be undefined and the |
|
186 * value of the global variable errno will be set accordingly. |
|
187 * @return true on success, notice that less than requested bytes could have |
|
188 * been read if the file was smaller |
|
189 */ |
|
190 bool |
|
191 ReadSysFile( |
|
192 const char* aFilename, |
|
193 char* aBuf, |
|
194 size_t aBufSize); |
|
195 |
|
196 /** |
|
197 * Parse the contents of a file, assuming it contains a decimal integer. |
|
198 * @return true on success |
|
199 */ |
|
200 bool |
|
201 ReadSysFile( |
|
202 const char* aFilename, |
|
203 int* aVal); |
|
204 |
|
205 /** |
|
206 * Parse the contents of a file, assuming it contains a boolean value |
|
207 * (either 0 or 1). |
|
208 * @return true on success |
|
209 */ |
|
210 bool |
|
211 ReadSysFile( |
|
212 const char* aFilename, |
|
213 bool* aVal); |
|
214 |
|
215 #endif /* (MOZ_WIDGET_GONK || DEBUG) && XP_UNIX */ |
|
216 |
|
217 } // namespace mozilla |
|
218 #endif |