Line data Source code
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 :
19 : #include "mozilla/Scoped.h"
20 : #include "nsIFile.h"
21 : #include <errno.h>
22 : #include <limits.h>
23 :
24 : namespace mozilla {
25 :
26 : #if defined(XP_WIN)
27 : typedef void* filedesc_t;
28 : typedef const wchar_t* pathstr_t;
29 : #else
30 : typedef int filedesc_t;
31 : typedef const char* pathstr_t;
32 : #endif
33 :
34 : /**
35 : * ScopedCloseFD is a RAII wrapper for POSIX file descriptors
36 : *
37 : * Instances |close()| their fds when they go out of scope.
38 : */
39 : struct ScopedCloseFDTraits
40 : {
41 : typedef int type;
42 2 : static type empty() { return -1; }
43 1 : static void release(type aFd)
44 : {
45 1 : if (aFd != -1) {
46 0 : while (close(aFd) == -1 && errno == EINTR) {
47 : }
48 : }
49 1 : }
50 : };
51 : typedef Scoped<ScopedCloseFDTraits> ScopedClose;
52 :
53 : #if defined(MOZILLA_INTERNAL_API)
54 :
55 : /**
56 : * AutoFDClose is a RAII wrapper for PRFileDesc.
57 : *
58 : * Instances |PR_Close| their fds when they go out of scope.
59 : **/
60 : struct ScopedClosePRFDTraits
61 : {
62 : typedef PRFileDesc* type;
63 946 : static type empty() { return nullptr; }
64 942 : static void release(type aFd)
65 : {
66 942 : if (aFd) {
67 934 : PR_Close(aFd);
68 : }
69 942 : }
70 : };
71 : typedef Scoped<ScopedClosePRFDTraits> AutoFDClose;
72 :
73 : /* RAII wrapper for FILE descriptors */
74 : struct ScopedCloseFileTraits
75 : {
76 : typedef FILE* type;
77 : static type empty() { return nullptr; }
78 : static void release(type aFile)
79 : {
80 : if (aFile) {
81 : fclose(aFile);
82 : }
83 : }
84 : };
85 : typedef Scoped<ScopedCloseFileTraits> ScopedCloseFile;
86 :
87 : /**
88 : * Fallocate efficiently and continuously allocates files via fallocate-type APIs.
89 : * This is useful for avoiding fragmentation.
90 : * On sucess the file be padded with zeros to grow to aLength.
91 : *
92 : * @param aFD file descriptor.
93 : * @param aLength length of file to grow to.
94 : * @return true on success.
95 : */
96 : bool fallocate(PRFileDesc* aFD, int64_t aLength);
97 :
98 : /**
99 : * Use readahead to preload shared libraries into the file cache before loading.
100 : * WARNING: This function should not be used without a telemetry field trial
101 : * demonstrating a clear performance improvement!
102 : *
103 : * @param aFile nsIFile representing path to shared library
104 : */
105 : void ReadAheadLib(nsIFile* aFile);
106 :
107 : /**
108 : * Use readahead to preload a file into the file cache before reading.
109 : * WARNING: This function should not be used without a telemetry field trial
110 : * demonstrating a clear performance improvement!
111 : *
112 : * @param aFile nsIFile representing path to shared library
113 : * @param aOffset Offset into the file to begin preloading
114 : * @param aCount Number of bytes to preload (SIZE_MAX implies file size)
115 : * @param aOutFd Pointer to file descriptor. If specified, ReadAheadFile will
116 : * return its internal, opened file descriptor instead of closing it.
117 : */
118 : void ReadAheadFile(nsIFile* aFile, const size_t aOffset = 0,
119 : const size_t aCount = SIZE_MAX,
120 : filedesc_t* aOutFd = nullptr);
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 :
164 : #if defined(MOZ_WIDGET_GONK) || defined(XP_UNIX)
165 : #define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
166 : typeof (exp) _rc; \
167 : do { \
168 : _rc = (exp); \
169 : } while (_rc == -1 && errno == EINTR); \
170 : _rc; \
171 : }))
172 : #endif
173 :
174 : /* Define ReadSysFile() and WriteSysFile() only on GONK to avoid unnecessary
175 : * libxul bloat. Also define it in debug builds, so that unit tests for it can
176 : * be written and run in non-GONK builds. */
177 : #if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX)
178 :
179 : #ifndef ReadSysFile_PRESENT
180 : #define ReadSysFile_PRESENT
181 : #endif /* ReadSysFile_PRESENT */
182 :
183 : #ifndef WriteSysFile_PRESENT
184 : #define WriteSysFile_PRESENT
185 : #endif /* WriteSysFile_PRESENT */
186 :
187 : /**
188 : * Read the contents of a file.
189 : * This function is intended for reading a single-lined text files from
190 : * /sys/. If the file ends with a newline ('\n') then it will be discarded.
191 : * The output buffer will always be '\0'-terminated on successful completion.
192 : * If aBufSize == 0, then this function will return true if the file exists
193 : * and is readable (it will not attempt to read anything from it).
194 : * On failure the contents of aBuf after this call will be undefined and the
195 : * value of the global variable errno will be set accordingly.
196 : * @return true on success, notice that less than requested bytes could have
197 : * been read if the file was smaller
198 : */
199 : bool ReadSysFile(const char* aFilename, char* aBuf, size_t aBufSize);
200 :
201 : /**
202 : * Parse the contents of a file, assuming it contains a decimal integer.
203 : * @return true on success
204 : */
205 : bool ReadSysFile(const char* aFilename, int* aVal);
206 :
207 : /**
208 : * Parse the contents of a file, assuming it contains a boolean value
209 : * (either 0 or 1).
210 : * @return true on success
211 : */
212 : bool ReadSysFile(const char* aFilename, bool* aVal);
213 :
214 : bool WriteSysFile(const char* aFilename, const char* aBuf);
215 :
216 : #endif /* (MOZ_WIDGET_GONK || DEBUG) && XP_UNIX */
217 :
218 : } // namespace mozilla
219 :
220 : #endif
|