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