/src/mozilla-central/dom/system/OSFileConstants.cpp
Line | Count | Source (jump to first uncovered line) |
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 file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "mozilla/DebugOnly.h" |
8 | | |
9 | | #include "fcntl.h" |
10 | | #include "errno.h" |
11 | | |
12 | | #include "prsystem.h" |
13 | | |
14 | | #if defined(XP_UNIX) |
15 | | #include "unistd.h" |
16 | | #include "dirent.h" |
17 | | #include "poll.h" |
18 | | #include "sys/stat.h" |
19 | | #if defined(XP_LINUX) |
20 | | #include <sys/vfs.h> |
21 | | #define statvfs statfs |
22 | | #define f_frsize f_bsize |
23 | | #else |
24 | | #include "sys/statvfs.h" |
25 | | #endif // defined(XP_LINUX) |
26 | | #if !defined(ANDROID) |
27 | | #include "sys/wait.h" |
28 | | #include <spawn.h> |
29 | | #endif // !defined(ANDROID) |
30 | | #endif // defined(XP_UNIX) |
31 | | |
32 | | #if defined(XP_LINUX) |
33 | | #include <linux/fadvise.h> |
34 | | #endif // defined(XP_LINUX) |
35 | | |
36 | | #if defined(XP_MACOSX) |
37 | | #include "copyfile.h" |
38 | | #endif // defined(XP_MACOSX) |
39 | | |
40 | | #if defined(XP_WIN) |
41 | | #include <windows.h> |
42 | | #include <accctrl.h> |
43 | | |
44 | | #ifndef PATH_MAX |
45 | | # define PATH_MAX MAX_PATH |
46 | | #endif |
47 | | |
48 | | #endif // defined(XP_WIN) |
49 | | |
50 | | #include "jsapi.h" |
51 | | #include "jsfriendapi.h" |
52 | | #include "BindingUtils.h" |
53 | | |
54 | | // Used to provide information on the OS |
55 | | |
56 | | #include "nsThreadUtils.h" |
57 | | #include "nsIObserverService.h" |
58 | | #include "nsIObserver.h" |
59 | | #include "nsDirectoryServiceUtils.h" |
60 | | #include "nsIXULRuntime.h" |
61 | | #include "nsIPropertyBag2.h" |
62 | | #include "nsXPCOMCIDInternal.h" |
63 | | #include "nsServiceManagerUtils.h" |
64 | | #include "nsString.h" |
65 | | #include "nsSystemInfo.h" |
66 | | #include "nsDirectoryServiceDefs.h" |
67 | | #include "nsXULAppAPI.h" |
68 | | #include "nsAppDirectoryServiceDefs.h" |
69 | | #include "mozJSComponentLoader.h" |
70 | | |
71 | | #include "mozilla/ClearOnShutdown.h" |
72 | | #include "mozilla/StaticPtr.h" |
73 | | #include "mozilla/UniquePtr.h" |
74 | | |
75 | | #include "OSFileConstants.h" |
76 | | #include "nsIOSFileConstantsService.h" |
77 | | #include "nsZipArchive.h" |
78 | | |
79 | | #if defined(__DragonFly__) || defined(__FreeBSD__) \ |
80 | | || defined(__NetBSD__) || defined(__OpenBSD__) |
81 | | #define __dd_fd dd_fd |
82 | | #endif |
83 | | |
84 | | /** |
85 | | * This module defines the basic libc constants (error numbers, open modes, |
86 | | * etc.) used by OS.File and possibly other OS-bound JavaScript libraries. |
87 | | */ |
88 | | |
89 | | |
90 | | namespace mozilla { |
91 | | |
92 | | namespace { |
93 | | |
94 | | StaticRefPtr<OSFileConstantsService> gInstance; |
95 | | |
96 | | } // anonymous namespace |
97 | | |
98 | | struct |
99 | | OSFileConstantsService::Paths |
100 | | { |
101 | | /** |
102 | | * The name of the directory holding all the libraries (libxpcom, libnss, etc.) |
103 | | */ |
104 | | nsString libDir; |
105 | | nsString tmpDir; |
106 | | nsString profileDir; |
107 | | nsString localProfileDir; |
108 | | /** |
109 | | * The user's home directory |
110 | | */ |
111 | | nsString homeDir; |
112 | | /** |
113 | | * The user's 'application data' directory. |
114 | | * Windows: |
115 | | * HOME = Documents and Settings\$USER\Application Data |
116 | | * UAppData = $HOME[\$vendor]\$name |
117 | | * |
118 | | * Unix: |
119 | | * HOME = ~ |
120 | | * UAppData = $HOME/.[$vendor/]$name |
121 | | * |
122 | | * Mac: |
123 | | * HOME = ~ |
124 | | * UAppData = $HOME/Library/Application Support/$name |
125 | | */ |
126 | | nsString userApplicationDataDir; |
127 | | |
128 | | #if defined(XP_MACOSX) |
129 | | /** |
130 | | * The user's Library directory. |
131 | | */ |
132 | | nsString macUserLibDir; |
133 | | #endif // defined(XP_MACOSX) |
134 | | |
135 | | Paths() |
136 | 0 | { |
137 | 0 | libDir.SetIsVoid(true); |
138 | 0 | tmpDir.SetIsVoid(true); |
139 | 0 | profileDir.SetIsVoid(true); |
140 | 0 | localProfileDir.SetIsVoid(true); |
141 | 0 | homeDir.SetIsVoid(true); |
142 | 0 | userApplicationDataDir.SetIsVoid(true); |
143 | 0 |
|
144 | | #if defined(XP_MACOSX) |
145 | | macUserLibDir.SetIsVoid(true); |
146 | | #endif // defined(XP_MACOSX) |
147 | | } |
148 | | }; |
149 | | |
150 | | /** |
151 | | * Return the path to one of the special directories. |
152 | | * |
153 | | * @param aKey The key to the special directory (e.g. "TmpD", "ProfD", ...) |
154 | | * @param aOutPath The path to the special directory. In case of error, |
155 | | * the string is set to void. |
156 | | */ |
157 | | nsresult GetPathToSpecialDir(const char *aKey, nsString& aOutPath) |
158 | 0 | { |
159 | 0 | nsCOMPtr<nsIFile> file; |
160 | 0 | nsresult rv = NS_GetSpecialDirectory(aKey, getter_AddRefs(file)); |
161 | 0 | if (NS_FAILED(rv) || !file) { |
162 | 0 | return rv; |
163 | 0 | } |
164 | 0 | |
165 | 0 | return file->GetPath(aOutPath); |
166 | 0 | } |
167 | | |
168 | | /** |
169 | | * In some cases, OSFileConstants may be instantiated before the |
170 | | * profile is setup. In such cases, |OS.Constants.Path.profileDir| and |
171 | | * |OS.Constants.Path.localProfileDir| are undefined. However, we want |
172 | | * to ensure that this does not break existing code, so that future |
173 | | * workers spawned after the profile is setup have these constants. |
174 | | * |
175 | | * For this purpose, we register an observer to set |mPaths->profileDir| |
176 | | * and |mPaths->localProfileDir| once the profile is setup. |
177 | | */ |
178 | | NS_IMETHODIMP |
179 | | OSFileConstantsService::Observe(nsISupports*, |
180 | | const char* aTopic, |
181 | | const char16_t*) |
182 | 0 | { |
183 | 0 | if (!mInitialized) { |
184 | 0 | // Initialization has not taken place, something is wrong, |
185 | 0 | // don't make things worse. |
186 | 0 | return NS_OK; |
187 | 0 | } |
188 | 0 | |
189 | 0 | nsresult rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, mPaths->profileDir); |
190 | 0 | if (NS_FAILED(rv)) { |
191 | 0 | return rv; |
192 | 0 | } |
193 | 0 | rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, mPaths->localProfileDir); |
194 | 0 | if (NS_FAILED(rv)) { |
195 | 0 | return rv; |
196 | 0 | } |
197 | 0 | |
198 | 0 | return NS_OK; |
199 | 0 | } |
200 | | |
201 | | /** |
202 | | * Perform the part of initialization that can only be |
203 | | * executed on the main thread. |
204 | | */ |
205 | | nsresult |
206 | | OSFileConstantsService::InitOSFileConstants() |
207 | 0 | { |
208 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
209 | 0 | if (mInitialized) { |
210 | 0 | return NS_OK; |
211 | 0 | } |
212 | 0 | |
213 | 0 | UniquePtr<Paths> paths(new Paths); |
214 | 0 |
|
215 | 0 | // Initialize paths->libDir |
216 | 0 | nsCOMPtr<nsIFile> file; |
217 | 0 | nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_LIBRARY_FILE, getter_AddRefs(file)); |
218 | 0 | if (NS_FAILED(rv)) { |
219 | 0 | return rv; |
220 | 0 | } |
221 | 0 | |
222 | 0 | nsCOMPtr<nsIFile> libDir; |
223 | 0 | rv = file->GetParent(getter_AddRefs(libDir)); |
224 | 0 | if (NS_FAILED(rv)) { |
225 | 0 | return rv; |
226 | 0 | } |
227 | 0 | |
228 | 0 | rv = libDir->GetPath(paths->libDir); |
229 | 0 | if (NS_FAILED(rv)) { |
230 | 0 | return rv; |
231 | 0 | } |
232 | 0 | |
233 | 0 | // Setup profileDir and localProfileDir immediately if possible (we |
234 | 0 | // assume that NS_APP_USER_PROFILE_50_DIR and |
235 | 0 | // NS_APP_USER_PROFILE_LOCAL_50_DIR are set simultaneously) |
236 | 0 | rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir); |
237 | 0 | if (NS_SUCCEEDED(rv)) { |
238 | 0 | rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, paths->localProfileDir); |
239 | 0 | } |
240 | 0 |
|
241 | 0 | // Otherwise, delay setup of profileDir/localProfileDir until they |
242 | 0 | // become available. |
243 | 0 | if (NS_FAILED(rv)) { |
244 | 0 | nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); |
245 | 0 | if (NS_FAILED(rv)) { |
246 | 0 | return rv; |
247 | 0 | } |
248 | 0 | rv = obsService->AddObserver(this, "profile-do-change", false); |
249 | 0 | if (NS_FAILED(rv)) { |
250 | 0 | return rv; |
251 | 0 | } |
252 | 0 | } |
253 | 0 | |
254 | 0 | // For other directories, ignore errors (they may be undefined on |
255 | 0 | // some platforms or in non-Firefox embeddings of Gecko). |
256 | 0 | |
257 | 0 | GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir); |
258 | 0 | GetPathToSpecialDir(NS_OS_HOME_DIR, paths->homeDir); |
259 | 0 | GetPathToSpecialDir(XRE_USER_APP_DATA_DIR, paths->userApplicationDataDir); |
260 | 0 |
|
261 | | #if defined(XP_MACOSX) |
262 | | GetPathToSpecialDir(NS_MAC_USER_LIB_DIR, paths->macUserLibDir); |
263 | | #endif // defined(XP_MACOSX) |
264 | |
|
265 | 0 | mPaths = std::move(paths); |
266 | 0 |
|
267 | 0 | // Get the umask from the system-info service. |
268 | 0 | // The property will always be present, but it will be zero on |
269 | 0 | // non-Unix systems. |
270 | 0 | // nsSystemInfo::gUserUmask is initialized by NS_InitXPCOM2 so we don't need |
271 | 0 | // to initialize the service. |
272 | 0 | mUserUmask = nsSystemInfo::gUserUmask; |
273 | 0 |
|
274 | 0 | mInitialized = true; |
275 | 0 | return NS_OK; |
276 | 0 | } |
277 | | |
278 | | /** |
279 | | * Define a simple read-only property holding an integer. |
280 | | * |
281 | | * @param name The name of the constant. Used both as the JS name for the |
282 | | * constant and to access its value. Must be defined. |
283 | | * |
284 | | * Produces a |ConstantSpec|. |
285 | | */ |
286 | | #define INT_CONSTANT(name) \ |
287 | | { #name, JS::Int32Value(name) } |
288 | | |
289 | | /** |
290 | | * Define a simple read-only property holding an unsigned integer. |
291 | | * |
292 | | * @param name The name of the constant. Used both as the JS name for the |
293 | | * constant and to access its value. Must be defined. |
294 | | * |
295 | | * Produces a |ConstantSpec|. |
296 | | */ |
297 | | #define UINT_CONSTANT(name) \ |
298 | | { #name, JS::NumberValue(name) } |
299 | | |
300 | | /** |
301 | | * End marker for ConstantSpec |
302 | | */ |
303 | | #define PROP_END { nullptr, JS::UndefinedValue() } |
304 | | |
305 | | |
306 | | // Define missing constants for Android |
307 | | #if !defined(S_IRGRP) |
308 | | #define S_IXOTH 0001 |
309 | | #define S_IWOTH 0002 |
310 | | #define S_IROTH 0004 |
311 | | #define S_IRWXO 0007 |
312 | | #define S_IXGRP 0010 |
313 | | #define S_IWGRP 0020 |
314 | | #define S_IRGRP 0040 |
315 | | #define S_IRWXG 0070 |
316 | | #define S_IXUSR 0100 |
317 | | #define S_IWUSR 0200 |
318 | | #define S_IRUSR 0400 |
319 | | #define S_IRWXU 0700 |
320 | | #endif // !defined(S_IRGRP) |
321 | | |
322 | | /** |
323 | | * The properties defined in libc. |
324 | | * |
325 | | * If you extend this list of properties, please |
326 | | * separate categories ("errors", "open", etc.), |
327 | | * keep properties organized by alphabetical order |
328 | | * and #ifdef-away properties that are not portable. |
329 | | */ |
330 | | static const dom::ConstantSpec gLibcProperties[] = |
331 | | { |
332 | | // Arguments for open |
333 | | INT_CONSTANT(O_APPEND), |
334 | | #if defined(O_CLOEXEC) |
335 | | INT_CONSTANT(O_CLOEXEC), |
336 | | #endif // defined(O_CLOEXEC) |
337 | | INT_CONSTANT(O_CREAT), |
338 | | #if defined(O_DIRECTORY) |
339 | | INT_CONSTANT(O_DIRECTORY), |
340 | | #endif // defined(O_DIRECTORY) |
341 | | #if defined(O_EVTONLY) |
342 | | INT_CONSTANT(O_EVTONLY), |
343 | | #endif // defined(O_EVTONLY) |
344 | | INT_CONSTANT(O_EXCL), |
345 | | #if defined(O_EXLOCK) |
346 | | INT_CONSTANT(O_EXLOCK), |
347 | | #endif // defined(O_EXLOCK) |
348 | | #if defined(O_LARGEFILE) |
349 | | INT_CONSTANT(O_LARGEFILE), |
350 | | #endif // defined(O_LARGEFILE) |
351 | | #if defined(O_NOFOLLOW) |
352 | | INT_CONSTANT(O_NOFOLLOW), |
353 | | #endif // defined(O_NOFOLLOW) |
354 | | #if defined(O_NONBLOCK) |
355 | | INT_CONSTANT(O_NONBLOCK), |
356 | | #endif // defined(O_NONBLOCK) |
357 | | INT_CONSTANT(O_RDONLY), |
358 | | INT_CONSTANT(O_RDWR), |
359 | | #if defined(O_RSYNC) |
360 | | INT_CONSTANT(O_RSYNC), |
361 | | #endif // defined(O_RSYNC) |
362 | | #if defined(O_SHLOCK) |
363 | | INT_CONSTANT(O_SHLOCK), |
364 | | #endif // defined(O_SHLOCK) |
365 | | #if defined(O_SYMLINK) |
366 | | INT_CONSTANT(O_SYMLINK), |
367 | | #endif // defined(O_SYMLINK) |
368 | | #if defined(O_SYNC) |
369 | | INT_CONSTANT(O_SYNC), |
370 | | #endif // defined(O_SYNC) |
371 | | INT_CONSTANT(O_TRUNC), |
372 | | INT_CONSTANT(O_WRONLY), |
373 | | |
374 | | #if defined(FD_CLOEXEC) |
375 | | INT_CONSTANT(FD_CLOEXEC), |
376 | | #endif // defined(FD_CLOEXEC) |
377 | | |
378 | | #if defined(AT_EACCESS) |
379 | | INT_CONSTANT(AT_EACCESS), |
380 | | #endif //defined(AT_EACCESS) |
381 | | #if defined(AT_FDCWD) |
382 | | INT_CONSTANT(AT_FDCWD), |
383 | | #endif //defined(AT_FDCWD) |
384 | | #if defined(AT_SYMLINK_NOFOLLOW) |
385 | | INT_CONSTANT(AT_SYMLINK_NOFOLLOW), |
386 | | #endif //defined(AT_SYMLINK_NOFOLLOW) |
387 | | |
388 | | #if defined(POSIX_FADV_SEQUENTIAL) |
389 | | INT_CONSTANT(POSIX_FADV_SEQUENTIAL), |
390 | | #endif //defined(POSIX_FADV_SEQUENTIAL) |
391 | | |
392 | | // access |
393 | | #if defined(F_OK) |
394 | | INT_CONSTANT(F_OK), |
395 | | INT_CONSTANT(R_OK), |
396 | | INT_CONSTANT(W_OK), |
397 | | INT_CONSTANT(X_OK), |
398 | | #endif // defined(F_OK) |
399 | | |
400 | | // modes |
401 | | INT_CONSTANT(S_IRGRP), |
402 | | INT_CONSTANT(S_IROTH), |
403 | | INT_CONSTANT(S_IRUSR), |
404 | | INT_CONSTANT(S_IRWXG), |
405 | | INT_CONSTANT(S_IRWXO), |
406 | | INT_CONSTANT(S_IRWXU), |
407 | | INT_CONSTANT(S_IWGRP), |
408 | | INT_CONSTANT(S_IWOTH), |
409 | | INT_CONSTANT(S_IWUSR), |
410 | | INT_CONSTANT(S_IXOTH), |
411 | | INT_CONSTANT(S_IXGRP), |
412 | | INT_CONSTANT(S_IXUSR), |
413 | | |
414 | | // seek |
415 | | INT_CONSTANT(SEEK_CUR), |
416 | | INT_CONSTANT(SEEK_END), |
417 | | INT_CONSTANT(SEEK_SET), |
418 | | |
419 | | #if defined(XP_UNIX) |
420 | | // poll |
421 | | INT_CONSTANT(POLLERR), |
422 | | INT_CONSTANT(POLLHUP), |
423 | | INT_CONSTANT(POLLIN), |
424 | | INT_CONSTANT(POLLNVAL), |
425 | | INT_CONSTANT(POLLOUT), |
426 | | |
427 | | // wait |
428 | | #if defined(WNOHANG) |
429 | | INT_CONSTANT(WNOHANG), |
430 | | #endif // defined(WNOHANG) |
431 | | |
432 | | // fcntl command values |
433 | | INT_CONSTANT(F_GETLK), |
434 | | INT_CONSTANT(F_SETFD), |
435 | | INT_CONSTANT(F_SETFL), |
436 | | INT_CONSTANT(F_SETLK), |
437 | | INT_CONSTANT(F_SETLKW), |
438 | | |
439 | | // flock type values |
440 | | INT_CONSTANT(F_RDLCK), |
441 | | INT_CONSTANT(F_WRLCK), |
442 | | INT_CONSTANT(F_UNLCK), |
443 | | |
444 | | // splice |
445 | | #if defined(SPLICE_F_MOVE) |
446 | | INT_CONSTANT(SPLICE_F_MOVE), |
447 | | #endif // defined(SPLICE_F_MOVE) |
448 | | #if defined(SPLICE_F_NONBLOCK) |
449 | | INT_CONSTANT(SPLICE_F_NONBLOCK), |
450 | | #endif // defined(SPLICE_F_NONBLOCK) |
451 | | #if defined(SPLICE_F_MORE) |
452 | | INT_CONSTANT(SPLICE_F_MORE), |
453 | | #endif // defined(SPLICE_F_MORE) |
454 | | #if defined(SPLICE_F_GIFT) |
455 | | INT_CONSTANT(SPLICE_F_GIFT), |
456 | | #endif // defined(SPLICE_F_GIFT) |
457 | | #endif // defined(XP_UNIX) |
458 | | // copyfile |
459 | | #if defined(COPYFILE_DATA) |
460 | | INT_CONSTANT(COPYFILE_DATA), |
461 | | INT_CONSTANT(COPYFILE_EXCL), |
462 | | INT_CONSTANT(COPYFILE_XATTR), |
463 | | INT_CONSTANT(COPYFILE_STAT), |
464 | | INT_CONSTANT(COPYFILE_ACL), |
465 | | INT_CONSTANT(COPYFILE_MOVE), |
466 | | #endif // defined(COPYFILE_DATA) |
467 | | |
468 | | // error values |
469 | | INT_CONSTANT(EACCES), |
470 | | INT_CONSTANT(EAGAIN), |
471 | | INT_CONSTANT(EBADF), |
472 | | INT_CONSTANT(EEXIST), |
473 | | INT_CONSTANT(EFAULT), |
474 | | INT_CONSTANT(EFBIG), |
475 | | INT_CONSTANT(EINVAL), |
476 | | INT_CONSTANT(EINTR), |
477 | | INT_CONSTANT(EIO), |
478 | | INT_CONSTANT(EISDIR), |
479 | | #if defined(ELOOP) // not defined with VC9 |
480 | | INT_CONSTANT(ELOOP), |
481 | | #endif // defined(ELOOP) |
482 | | INT_CONSTANT(EMFILE), |
483 | | INT_CONSTANT(ENAMETOOLONG), |
484 | | INT_CONSTANT(ENFILE), |
485 | | INT_CONSTANT(ENOENT), |
486 | | INT_CONSTANT(ENOMEM), |
487 | | INT_CONSTANT(ENOSPC), |
488 | | INT_CONSTANT(ENOTDIR), |
489 | | INT_CONSTANT(ENXIO), |
490 | | #if defined(EOPNOTSUPP) // not defined with VC 9 |
491 | | INT_CONSTANT(EOPNOTSUPP), |
492 | | #endif // defined(EOPNOTSUPP) |
493 | | #if defined(EOVERFLOW) // not defined with VC 9 |
494 | | INT_CONSTANT(EOVERFLOW), |
495 | | #endif // defined(EOVERFLOW) |
496 | | INT_CONSTANT(EPERM), |
497 | | INT_CONSTANT(ERANGE), |
498 | | #if defined(ETIMEDOUT) // not defined with VC 9 |
499 | | INT_CONSTANT(ETIMEDOUT), |
500 | | #endif // defined(ETIMEDOUT) |
501 | | #if defined(EWOULDBLOCK) // not defined with VC 9 |
502 | | INT_CONSTANT(EWOULDBLOCK), |
503 | | #endif // defined(EWOULDBLOCK) |
504 | | INT_CONSTANT(EXDEV), |
505 | | |
506 | | #if defined(DT_UNKNOWN) |
507 | | // Constants for |readdir| |
508 | | INT_CONSTANT(DT_UNKNOWN), |
509 | | INT_CONSTANT(DT_FIFO), |
510 | | INT_CONSTANT(DT_CHR), |
511 | | INT_CONSTANT(DT_DIR), |
512 | | INT_CONSTANT(DT_BLK), |
513 | | INT_CONSTANT(DT_REG), |
514 | | INT_CONSTANT(DT_LNK), |
515 | | INT_CONSTANT(DT_SOCK), |
516 | | #endif // defined(DT_UNKNOWN) |
517 | | |
518 | | #if defined(S_IFIFO) |
519 | | // Constants for |stat| |
520 | | INT_CONSTANT(S_IFMT), |
521 | | INT_CONSTANT(S_IFIFO), |
522 | | INT_CONSTANT(S_IFCHR), |
523 | | INT_CONSTANT(S_IFDIR), |
524 | | INT_CONSTANT(S_IFBLK), |
525 | | INT_CONSTANT(S_IFREG), |
526 | | INT_CONSTANT(S_IFLNK), |
527 | | INT_CONSTANT(S_IFSOCK), |
528 | | #endif // defined(S_IFIFO) |
529 | | |
530 | | INT_CONSTANT(PATH_MAX), |
531 | | |
532 | | // Constants used to define data structures |
533 | | // |
534 | | // Many data structures have different fields/sizes/etc. on |
535 | | // various OSes / versions of the same OS / platforms. For these |
536 | | // data structures, we need to compute and export from C the size |
537 | | // and, if necessary, the offset of fields, so as to be able to |
538 | | // define the structure in JS. |
539 | | |
540 | | #if defined(XP_UNIX) |
541 | | // The size of |mode_t|. |
542 | | { "OSFILE_SIZEOF_MODE_T", JS::Int32Value(sizeof (mode_t)) }, |
543 | | |
544 | | // The size of |gid_t|. |
545 | | { "OSFILE_SIZEOF_GID_T", JS::Int32Value(sizeof (gid_t)) }, |
546 | | |
547 | | // The size of |uid_t|. |
548 | | { "OSFILE_SIZEOF_UID_T", JS::Int32Value(sizeof (uid_t)) }, |
549 | | |
550 | | // The size of |time_t|. |
551 | | { "OSFILE_SIZEOF_TIME_T", JS::Int32Value(sizeof (time_t)) }, |
552 | | |
553 | | // The size of |fsblkcnt_t|. |
554 | | { "OSFILE_SIZEOF_FSBLKCNT_T", JS::Int32Value(sizeof (fsblkcnt_t)) }, |
555 | | |
556 | | #if !defined(ANDROID) |
557 | | // The size of |posix_spawn_file_actions_t|. |
558 | | { "OSFILE_SIZEOF_POSIX_SPAWN_FILE_ACTIONS_T", JS::Int32Value(sizeof (posix_spawn_file_actions_t)) }, |
559 | | #endif // !defined(ANDROID) |
560 | | |
561 | | // Defining |dirent|. |
562 | | // Size |
563 | | { "OSFILE_SIZEOF_DIRENT", JS::Int32Value(sizeof (dirent)) }, |
564 | | |
565 | | // Defining |flock|. |
566 | | #if defined(XP_UNIX) |
567 | | { "OSFILE_SIZEOF_FLOCK", JS::Int32Value(sizeof (struct flock)) }, |
568 | | { "OSFILE_OFFSETOF_FLOCK_L_START", JS::Int32Value(offsetof (struct flock, l_start)) }, |
569 | | { "OSFILE_OFFSETOF_FLOCK_L_LEN", JS::Int32Value(offsetof (struct flock, l_len)) }, |
570 | | { "OSFILE_OFFSETOF_FLOCK_L_PID", JS::Int32Value(offsetof (struct flock, l_pid)) }, |
571 | | { "OSFILE_OFFSETOF_FLOCK_L_TYPE", JS::Int32Value(offsetof (struct flock, l_type)) }, |
572 | | { "OSFILE_OFFSETOF_FLOCK_L_WHENCE", JS::Int32Value(offsetof (struct flock, l_whence)) }, |
573 | | #endif // defined(XP_UNIX) |
574 | | // Offset of field |d_name|. |
575 | | { "OSFILE_OFFSETOF_DIRENT_D_NAME", JS::Int32Value(offsetof (struct dirent, d_name)) }, |
576 | | // An upper bound to the length of field |d_name| of struct |dirent|. |
577 | | // (may not be exact, depending on padding). |
578 | | { "OSFILE_SIZEOF_DIRENT_D_NAME", JS::Int32Value(sizeof (struct dirent) - offsetof (struct dirent, d_name)) }, |
579 | | |
580 | | // Defining |timeval|. |
581 | | { "OSFILE_SIZEOF_TIMEVAL", JS::Int32Value(sizeof (struct timeval)) }, |
582 | | { "OSFILE_OFFSETOF_TIMEVAL_TV_SEC", JS::Int32Value(offsetof (struct timeval, tv_sec)) }, |
583 | | { "OSFILE_OFFSETOF_TIMEVAL_TV_USEC", JS::Int32Value(offsetof (struct timeval, tv_usec)) }, |
584 | | |
585 | | #if defined(DT_UNKNOWN) |
586 | | // Position of field |d_type| in |dirent| |
587 | | // Not strictly posix, but seems defined on all platforms |
588 | | // except mingw32. |
589 | | { "OSFILE_OFFSETOF_DIRENT_D_TYPE", JS::Int32Value(offsetof (struct dirent, d_type)) }, |
590 | | #endif // defined(DT_UNKNOWN) |
591 | | |
592 | | // Under MacOS X and BSDs, |dirfd| is a macro rather than a |
593 | | // function, so we need a little help to get it to work |
594 | | #if defined(dirfd) |
595 | | { "OSFILE_SIZEOF_DIR", JS::Int32Value(sizeof (DIR)) }, |
596 | | |
597 | | { "OSFILE_OFFSETOF_DIR_DD_FD", JS::Int32Value(offsetof (DIR, __dd_fd)) }, |
598 | | #endif |
599 | | |
600 | | // Defining |stat| |
601 | | |
602 | | { "OSFILE_SIZEOF_STAT", JS::Int32Value(sizeof (struct stat)) }, |
603 | | |
604 | | { "OSFILE_OFFSETOF_STAT_ST_MODE", JS::Int32Value(offsetof (struct stat, st_mode)) }, |
605 | | { "OSFILE_OFFSETOF_STAT_ST_UID", JS::Int32Value(offsetof (struct stat, st_uid)) }, |
606 | | { "OSFILE_OFFSETOF_STAT_ST_GID", JS::Int32Value(offsetof (struct stat, st_gid)) }, |
607 | | { "OSFILE_OFFSETOF_STAT_ST_SIZE", JS::Int32Value(offsetof (struct stat, st_size)) }, |
608 | | |
609 | | #if defined(HAVE_ST_ATIMESPEC) |
610 | | { "OSFILE_OFFSETOF_STAT_ST_ATIME", JS::Int32Value(offsetof (struct stat, st_atimespec)) }, |
611 | | { "OSFILE_OFFSETOF_STAT_ST_MTIME", JS::Int32Value(offsetof (struct stat, st_mtimespec)) }, |
612 | | { "OSFILE_OFFSETOF_STAT_ST_CTIME", JS::Int32Value(offsetof (struct stat, st_ctimespec)) }, |
613 | | #else |
614 | | { "OSFILE_OFFSETOF_STAT_ST_ATIME", JS::Int32Value(offsetof (struct stat, st_atime)) }, |
615 | | { "OSFILE_OFFSETOF_STAT_ST_MTIME", JS::Int32Value(offsetof (struct stat, st_mtime)) }, |
616 | | { "OSFILE_OFFSETOF_STAT_ST_CTIME", JS::Int32Value(offsetof (struct stat, st_ctime)) }, |
617 | | #endif // defined(HAVE_ST_ATIME) |
618 | | |
619 | | // Several OSes have a birthtime field. For the moment, supporting only Darwin. |
620 | | #if defined(_DARWIN_FEATURE_64_BIT_INODE) |
621 | | { "OSFILE_OFFSETOF_STAT_ST_BIRTHTIME", JS::Int32Value(offsetof (struct stat, st_birthtime)) }, |
622 | | #endif // defined(_DARWIN_FEATURE_64_BIT_INODE) |
623 | | |
624 | | // Defining |statvfs| |
625 | | |
626 | | { "OSFILE_SIZEOF_STATVFS", JS::Int32Value(sizeof (struct statvfs)) }, |
627 | | |
628 | | { "OSFILE_OFFSETOF_STATVFS_F_FRSIZE", JS::Int32Value(offsetof (struct statvfs, f_frsize)) }, |
629 | | { "OSFILE_OFFSETOF_STATVFS_F_BAVAIL", JS::Int32Value(offsetof (struct statvfs, f_bavail)) }, |
630 | | |
631 | | #endif // defined(XP_UNIX) |
632 | | |
633 | | |
634 | | |
635 | | // System configuration |
636 | | |
637 | | // Under MacOSX, to avoid using deprecated functions that do not |
638 | | // match the constants we define in this object (including |
639 | | // |sizeof|/|offsetof| stuff, but not only), for a number of |
640 | | // functions, we need to adapt the name of the symbols we are using, |
641 | | // whenever macro _DARWIN_FEATURE_64_BIT_INODE is set. We export |
642 | | // this value to be able to do so from JavaScript. |
643 | | #if defined(_DARWIN_FEATURE_64_BIT_INODE) |
644 | | { "_DARWIN_FEATURE_64_BIT_INODE", JS::Int32Value(1) }, |
645 | | #endif // defined(_DARWIN_FEATURE_64_BIT_INODE) |
646 | | |
647 | | // Similar feature for Linux |
648 | | #if defined(_STAT_VER) |
649 | | INT_CONSTANT(_STAT_VER), |
650 | | #endif // defined(_STAT_VER) |
651 | | |
652 | | PROP_END |
653 | | }; |
654 | | |
655 | | |
656 | | #if defined(XP_WIN) |
657 | | /** |
658 | | * The properties defined in windows.h. |
659 | | * |
660 | | * If you extend this list of properties, please |
661 | | * separate categories ("errors", "open", etc.), |
662 | | * keep properties organized by alphabetical order |
663 | | * and #ifdef-away properties that are not portable. |
664 | | */ |
665 | | static const dom::ConstantSpec gWinProperties[] = |
666 | | { |
667 | | // FormatMessage flags |
668 | | INT_CONSTANT(FORMAT_MESSAGE_FROM_SYSTEM), |
669 | | INT_CONSTANT(FORMAT_MESSAGE_IGNORE_INSERTS), |
670 | | |
671 | | // The max length of paths |
672 | | INT_CONSTANT(MAX_PATH), |
673 | | |
674 | | // CreateFile desired access |
675 | | INT_CONSTANT(GENERIC_ALL), |
676 | | INT_CONSTANT(GENERIC_EXECUTE), |
677 | | INT_CONSTANT(GENERIC_READ), |
678 | | INT_CONSTANT(GENERIC_WRITE), |
679 | | |
680 | | // CreateFile share mode |
681 | | INT_CONSTANT(FILE_SHARE_DELETE), |
682 | | INT_CONSTANT(FILE_SHARE_READ), |
683 | | INT_CONSTANT(FILE_SHARE_WRITE), |
684 | | |
685 | | // CreateFile creation disposition |
686 | | INT_CONSTANT(CREATE_ALWAYS), |
687 | | INT_CONSTANT(CREATE_NEW), |
688 | | INT_CONSTANT(OPEN_ALWAYS), |
689 | | INT_CONSTANT(OPEN_EXISTING), |
690 | | INT_CONSTANT(TRUNCATE_EXISTING), |
691 | | |
692 | | // CreateFile attributes |
693 | | INT_CONSTANT(FILE_ATTRIBUTE_ARCHIVE), |
694 | | INT_CONSTANT(FILE_ATTRIBUTE_DIRECTORY), |
695 | | INT_CONSTANT(FILE_ATTRIBUTE_HIDDEN), |
696 | | INT_CONSTANT(FILE_ATTRIBUTE_NORMAL), |
697 | | INT_CONSTANT(FILE_ATTRIBUTE_READONLY), |
698 | | INT_CONSTANT(FILE_ATTRIBUTE_REPARSE_POINT), |
699 | | INT_CONSTANT(FILE_ATTRIBUTE_SYSTEM), |
700 | | INT_CONSTANT(FILE_ATTRIBUTE_TEMPORARY), |
701 | | INT_CONSTANT(FILE_FLAG_BACKUP_SEMANTICS), |
702 | | |
703 | | // CreateFile error constant |
704 | | { "INVALID_HANDLE_VALUE", JS::Int32Value(INT_PTR(INVALID_HANDLE_VALUE)) }, |
705 | | |
706 | | |
707 | | // CreateFile flags |
708 | | INT_CONSTANT(FILE_FLAG_DELETE_ON_CLOSE), |
709 | | |
710 | | // SetFilePointer methods |
711 | | INT_CONSTANT(FILE_BEGIN), |
712 | | INT_CONSTANT(FILE_CURRENT), |
713 | | INT_CONSTANT(FILE_END), |
714 | | |
715 | | // SetFilePointer error constant |
716 | | UINT_CONSTANT(INVALID_SET_FILE_POINTER), |
717 | | |
718 | | // File attributes |
719 | | INT_CONSTANT(FILE_ATTRIBUTE_DIRECTORY), |
720 | | |
721 | | |
722 | | // MoveFile flags |
723 | | INT_CONSTANT(MOVEFILE_COPY_ALLOWED), |
724 | | INT_CONSTANT(MOVEFILE_REPLACE_EXISTING), |
725 | | |
726 | | // GetFileAttributes error constant |
727 | | INT_CONSTANT(INVALID_FILE_ATTRIBUTES), |
728 | | |
729 | | // GetNamedSecurityInfo and SetNamedSecurityInfo constants |
730 | | INT_CONSTANT(UNPROTECTED_DACL_SECURITY_INFORMATION), |
731 | | INT_CONSTANT(SE_FILE_OBJECT), |
732 | | INT_CONSTANT(DACL_SECURITY_INFORMATION), |
733 | | |
734 | | // Errors |
735 | | INT_CONSTANT(ERROR_INVALID_HANDLE), |
736 | | INT_CONSTANT(ERROR_ACCESS_DENIED), |
737 | | INT_CONSTANT(ERROR_DIR_NOT_EMPTY), |
738 | | INT_CONSTANT(ERROR_FILE_EXISTS), |
739 | | INT_CONSTANT(ERROR_ALREADY_EXISTS), |
740 | | INT_CONSTANT(ERROR_FILE_NOT_FOUND), |
741 | | INT_CONSTANT(ERROR_NO_MORE_FILES), |
742 | | INT_CONSTANT(ERROR_PATH_NOT_FOUND), |
743 | | INT_CONSTANT(ERROR_BAD_ARGUMENTS), |
744 | | INT_CONSTANT(ERROR_SHARING_VIOLATION), |
745 | | INT_CONSTANT(ERROR_NOT_SUPPORTED), |
746 | | |
747 | | PROP_END |
748 | | }; |
749 | | #endif // defined(XP_WIN) |
750 | | |
751 | | |
752 | | /** |
753 | | * Get a field of an object as an object. |
754 | | * |
755 | | * If the field does not exist, create it. If it exists but is not an |
756 | | * object, throw a JS error. |
757 | | */ |
758 | | JSObject *GetOrCreateObjectProperty(JSContext *cx, JS::Handle<JSObject*> aObject, |
759 | | const char *aProperty) |
760 | 0 | { |
761 | 0 | JS::Rooted<JS::Value> val(cx); |
762 | 0 | if (!JS_GetProperty(cx, aObject, aProperty, &val)) { |
763 | 0 | return nullptr; |
764 | 0 | } |
765 | 0 | if (!val.isUndefined()) { |
766 | 0 | if (val.isObject()) { |
767 | 0 | return &val.toObject(); |
768 | 0 | } |
769 | 0 | |
770 | 0 | JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr, |
771 | 0 | JSMSG_UNEXPECTED_TYPE, |
772 | 0 | aProperty, "not an object"); |
773 | 0 | return nullptr; |
774 | 0 | } |
775 | 0 | return JS_DefineObject(cx, aObject, aProperty, nullptr, JSPROP_ENUMERATE); |
776 | 0 | } |
777 | | |
778 | | /** |
779 | | * Set a property of an object from a nsString. |
780 | | * |
781 | | * If the nsString is void (i.e. IsVoid is true), do nothing. |
782 | | */ |
783 | | bool SetStringProperty(JSContext *cx, JS::Handle<JSObject*> aObject, const char *aProperty, |
784 | | const nsString aValue) |
785 | 0 | { |
786 | 0 | if (aValue.IsVoid()) { |
787 | 0 | return true; |
788 | 0 | } |
789 | 0 | JSString* strValue = JS_NewUCStringCopyZ(cx, aValue.get()); |
790 | 0 | NS_ENSURE_TRUE(strValue, false); |
791 | 0 | JS::Rooted<JS::Value> valValue(cx, JS::StringValue(strValue)); |
792 | 0 | return JS_SetProperty(cx, aObject, aProperty, valValue); |
793 | 0 | } |
794 | | |
795 | | /** |
796 | | * Define OS-specific constants. |
797 | | * |
798 | | * This function creates or uses JS object |OS.Constants| to store |
799 | | * all its constants. |
800 | | */ |
801 | | bool |
802 | | OSFileConstantsService::DefineOSFileConstants(JSContext* aCx, |
803 | | JS::Handle<JSObject*> aGlobal) |
804 | 0 | { |
805 | 0 | if (!mInitialized) { |
806 | 0 | JS_ReportErrorNumberASCII(aCx, js::GetErrorMessage, nullptr, |
807 | 0 | JSMSG_CANT_OPEN, |
808 | 0 | "OSFileConstants", "initialization has failed"); |
809 | 0 | return false; |
810 | 0 | } |
811 | 0 | |
812 | 0 | JS::Rooted<JSObject*> objOS(aCx); |
813 | 0 | if (!(objOS = GetOrCreateObjectProperty(aCx, aGlobal, "OS"))) { |
814 | 0 | return false; |
815 | 0 | } |
816 | 0 | JS::Rooted<JSObject*> objConstants(aCx); |
817 | 0 | if (!(objConstants = GetOrCreateObjectProperty(aCx, objOS, "Constants"))) { |
818 | 0 | return false; |
819 | 0 | } |
820 | 0 | |
821 | 0 | // Build OS.Constants.libc |
822 | 0 | |
823 | 0 | JS::Rooted<JSObject*> objLibc(aCx); |
824 | 0 | if (!(objLibc = GetOrCreateObjectProperty(aCx, objConstants, "libc"))) { |
825 | 0 | return false; |
826 | 0 | } |
827 | 0 | if (!dom::DefineConstants(aCx, objLibc, gLibcProperties)) { |
828 | 0 | return false; |
829 | 0 | } |
830 | 0 | |
831 | | #if defined(XP_WIN) |
832 | | // Build OS.Constants.Win |
833 | | |
834 | | JS::Rooted<JSObject*> objWin(aCx); |
835 | | if (!(objWin = GetOrCreateObjectProperty(aCx, objConstants, "Win"))) { |
836 | | return false; |
837 | | } |
838 | | if (!dom::DefineConstants(aCx, objWin, gWinProperties)) { |
839 | | return false; |
840 | | } |
841 | | #endif // defined(XP_WIN) |
842 | | |
843 | 0 | // Build OS.Constants.Sys |
844 | 0 | |
845 | 0 | JS::Rooted<JSObject*> objSys(aCx); |
846 | 0 | if (!(objSys = GetOrCreateObjectProperty(aCx, objConstants, "Sys"))) { |
847 | 0 | return false; |
848 | 0 | } |
849 | 0 | |
850 | 0 | nsCOMPtr<nsIXULRuntime> runtime = do_GetService(XULRUNTIME_SERVICE_CONTRACTID); |
851 | 0 | if (runtime) { |
852 | 0 | nsAutoCString os; |
853 | 0 | DebugOnly<nsresult> rv = runtime->GetOS(os); |
854 | 0 | MOZ_ASSERT(NS_SUCCEEDED(rv)); |
855 | 0 |
|
856 | 0 | JSString* strVersion = JS_NewStringCopyZ(aCx, os.get()); |
857 | 0 | if (!strVersion) { |
858 | 0 | return false; |
859 | 0 | } |
860 | 0 | |
861 | 0 | JS::Rooted<JS::Value> valVersion(aCx, JS::StringValue(strVersion)); |
862 | 0 | if (!JS_SetProperty(aCx, objSys, "Name", valVersion)) { |
863 | 0 | return false; |
864 | 0 | } |
865 | 0 | } |
866 | 0 | |
867 | | #if defined(DEBUG) |
868 | | JS::Rooted<JS::Value> valDebug(aCx, JS::TrueValue()); |
869 | | if (!JS_SetProperty(aCx, objSys, "DEBUG", valDebug)) { |
870 | | return false; |
871 | | } |
872 | | #endif |
873 | | |
874 | 0 | #if defined(HAVE_64BIT_BUILD) |
875 | 0 | JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(64)); |
876 | | #else |
877 | | JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(32)); |
878 | | #endif //defined (HAVE_64BIT_BUILD) |
879 | 0 | if (!JS_SetProperty(aCx, objSys, "bits", valBits)) { |
880 | 0 | return false; |
881 | 0 | } |
882 | 0 | |
883 | 0 | if (!JS_DefineProperty(aCx, objSys, "umask", mUserUmask, |
884 | 0 | JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) { |
885 | 0 | return false; |
886 | 0 | } |
887 | 0 | |
888 | 0 | // Build OS.Constants.Path |
889 | 0 | |
890 | 0 | JS::Rooted<JSObject*> objPath(aCx); |
891 | 0 | if (!(objPath = GetOrCreateObjectProperty(aCx, objConstants, "Path"))) { |
892 | 0 | return false; |
893 | 0 | } |
894 | 0 | |
895 | 0 | // Locate libxul |
896 | 0 | // Note that we don't actually provide the full path, only the name of the |
897 | 0 | // library, which is sufficient to link to the library using js-ctypes. |
898 | 0 | |
899 | | #if defined(XP_MACOSX) |
900 | | // Under MacOS X, for some reason, libxul is called simply "XUL", |
901 | | // and we need to provide the full path. |
902 | | nsAutoString libxul; |
903 | | libxul.Append(mPaths->libDir); |
904 | | libxul.AppendLiteral("/XUL"); |
905 | | #else |
906 | | // On other platforms, libxul is a library "xul" with regular |
907 | 0 | // library prefix/suffix. |
908 | 0 | nsAutoString libxul; |
909 | 0 | libxul.AppendLiteral(MOZ_DLL_PREFIX); |
910 | 0 | libxul.AppendLiteral("xul"); |
911 | 0 | libxul.AppendLiteral(MOZ_DLL_SUFFIX); |
912 | 0 | #endif // defined(XP_MACOSX) |
913 | 0 |
|
914 | 0 | if (!SetStringProperty(aCx, objPath, "libxul", libxul)) { |
915 | 0 | return false; |
916 | 0 | } |
917 | 0 | |
918 | 0 | if (!SetStringProperty(aCx, objPath, "libDir", mPaths->libDir)) { |
919 | 0 | return false; |
920 | 0 | } |
921 | 0 | |
922 | 0 | if (!SetStringProperty(aCx, objPath, "tmpDir", mPaths->tmpDir)) { |
923 | 0 | return false; |
924 | 0 | } |
925 | 0 | |
926 | 0 | // Configure profileDir only if it is available at this stage |
927 | 0 | if (!mPaths->profileDir.IsVoid() |
928 | 0 | && !SetStringProperty(aCx, objPath, "profileDir", mPaths->profileDir)) { |
929 | 0 | return false; |
930 | 0 | } |
931 | 0 | |
932 | 0 | // Configure localProfileDir only if it is available at this stage |
933 | 0 | if (!mPaths->localProfileDir.IsVoid() |
934 | 0 | && !SetStringProperty(aCx, objPath, "localProfileDir", mPaths->localProfileDir)) { |
935 | 0 | return false; |
936 | 0 | } |
937 | 0 | |
938 | 0 | if (!SetStringProperty(aCx, objPath, "homeDir", mPaths->homeDir)) { |
939 | 0 | return false; |
940 | 0 | } |
941 | 0 | |
942 | 0 | if (!SetStringProperty(aCx, objPath, "userApplicationDataDir", mPaths->userApplicationDataDir)) { |
943 | 0 | return false; |
944 | 0 | } |
945 | 0 | |
946 | | #if defined(XP_MACOSX) |
947 | | if (!SetStringProperty(aCx, objPath, "macUserLibDir", mPaths->macUserLibDir)) { |
948 | | return false; |
949 | | } |
950 | | #endif // defined(XP_MACOSX) |
951 | | |
952 | 0 | // sqlite3 is linked from different places depending on the platform |
953 | 0 | nsAutoString libsqlite3; |
954 | | #if defined(ANDROID) |
955 | | // On Android, we use the system's libsqlite3 |
956 | | libsqlite3.AppendLiteral(MOZ_DLL_PREFIX); |
957 | | libsqlite3.AppendLiteral("sqlite3"); |
958 | | libsqlite3.AppendLiteral(MOZ_DLL_SUFFIX); |
959 | | #elif defined(XP_WIN) |
960 | | // On Windows, for some reason, this is part of nss3.dll |
961 | | libsqlite3.AppendLiteral(MOZ_DLL_PREFIX); |
962 | | libsqlite3.AppendLiteral("nss3"); |
963 | | libsqlite3.AppendLiteral(MOZ_DLL_SUFFIX); |
964 | | #else |
965 | | // On other platforms, we link sqlite3 into libxul |
966 | 0 | libsqlite3 = libxul; |
967 | 0 | #endif // defined(ANDROID) || defined(XP_WIN) |
968 | 0 |
|
969 | 0 | if (!SetStringProperty(aCx, objPath, "libsqlite3", libsqlite3)) { |
970 | 0 | return false; |
971 | 0 | } |
972 | 0 | |
973 | 0 | return true; |
974 | 0 | } |
975 | | |
976 | | NS_IMPL_ISUPPORTS(OSFileConstantsService, nsIOSFileConstantsService, |
977 | | nsIObserver) |
978 | | |
979 | | /* static */ already_AddRefed<OSFileConstantsService> |
980 | | OSFileConstantsService::GetOrCreate() |
981 | 0 | { |
982 | 0 | if (!gInstance) { |
983 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
984 | 0 |
|
985 | 0 | RefPtr<OSFileConstantsService> service = new OSFileConstantsService(); |
986 | 0 | nsresult rv = service->InitOSFileConstants(); |
987 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
988 | 0 | return nullptr; |
989 | 0 | } |
990 | 0 | |
991 | 0 | gInstance = service.forget(); |
992 | 0 | ClearOnShutdown(&gInstance); |
993 | 0 | } |
994 | 0 |
|
995 | 0 | RefPtr<OSFileConstantsService> copy = gInstance; |
996 | 0 | return copy.forget(); |
997 | 0 | } |
998 | | |
999 | | OSFileConstantsService::OSFileConstantsService() |
1000 | | : mInitialized(false) |
1001 | | , mUserUmask(0) |
1002 | 0 | { |
1003 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1004 | 0 | } |
1005 | | |
1006 | | OSFileConstantsService::~OSFileConstantsService() |
1007 | 0 | { |
1008 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1009 | 0 | } |
1010 | | |
1011 | | NS_IMETHODIMP |
1012 | | OSFileConstantsService::Init(JSContext *aCx) |
1013 | 0 | { |
1014 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1015 | 0 |
|
1016 | 0 | nsresult rv = InitOSFileConstants(); |
1017 | 0 | if (NS_FAILED(rv)) { |
1018 | 0 | return rv; |
1019 | 0 | } |
1020 | 0 | |
1021 | 0 | mozJSComponentLoader* loader = mozJSComponentLoader::Get(); |
1022 | 0 | JS::Rooted<JSObject*> targetObj(aCx); |
1023 | 0 | loader->FindTargetObject(aCx, &targetObj); |
1024 | 0 |
|
1025 | 0 | if (!DefineOSFileConstants(aCx, targetObj)) { |
1026 | 0 | return NS_ERROR_FAILURE; |
1027 | 0 | } |
1028 | 0 | |
1029 | 0 | return NS_OK; |
1030 | 0 | } |
1031 | | |
1032 | | } // namespace mozilla |