forked from mirrors/gecko-dev
		
	 00e98538aa
			
		
	
	
		00e98538aa
		
	
	
	
	
		
			
			Differential Revision: https://phabricator.services.mozilla.com/D21106 --HG-- extra : rebase_source : ea3f51c2c11247114deccbc86e90fb02b8a97257
		
			
				
	
	
		
			983 lines
		
	
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			983 lines
		
	
	
	
		
			28 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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/. */
 | |
| 
 | |
| #include "mozilla/DebugOnly.h"
 | |
| 
 | |
| #include "fcntl.h"
 | |
| #include "errno.h"
 | |
| 
 | |
| #include "prsystem.h"
 | |
| 
 | |
| #if defined(XP_UNIX)
 | |
| #  include "unistd.h"
 | |
| #  include "dirent.h"
 | |
| #  include "poll.h"
 | |
| #  include "sys/stat.h"
 | |
| #  if defined(XP_LINUX)
 | |
| #    include <sys/vfs.h>
 | |
| #    define statvfs statfs
 | |
| #    define f_frsize f_bsize
 | |
| #  else
 | |
| #    include "sys/statvfs.h"
 | |
| #  endif  // defined(XP_LINUX)
 | |
| #  if !defined(ANDROID)
 | |
| #    include "sys/wait.h"
 | |
| #    include <spawn.h>
 | |
| #  endif  // !defined(ANDROID)
 | |
| #endif    // defined(XP_UNIX)
 | |
| 
 | |
| #if defined(XP_LINUX)
 | |
| #  include <linux/fadvise.h>
 | |
| #endif  // defined(XP_LINUX)
 | |
| 
 | |
| #if defined(XP_MACOSX)
 | |
| #  include "copyfile.h"
 | |
| #endif  // defined(XP_MACOSX)
 | |
| 
 | |
| #if defined(XP_WIN)
 | |
| #  include <windows.h>
 | |
| #  include <accctrl.h>
 | |
| 
 | |
| #  ifndef PATH_MAX
 | |
| #    define PATH_MAX MAX_PATH
 | |
| #  endif
 | |
| 
 | |
| #endif  // defined(XP_WIN)
 | |
| 
 | |
| #include "jsapi.h"
 | |
| #include "jsfriendapi.h"
 | |
| #include "BindingUtils.h"
 | |
| 
 | |
| // Used to provide information on the OS
 | |
| 
 | |
| #include "nsThreadUtils.h"
 | |
| #include "nsIObserverService.h"
 | |
| #include "nsIObserver.h"
 | |
| #include "nsDirectoryServiceUtils.h"
 | |
| #include "nsIXULRuntime.h"
 | |
| #include "nsIPropertyBag2.h"
 | |
| #include "nsXPCOMCIDInternal.h"
 | |
| #include "nsServiceManagerUtils.h"
 | |
| #include "nsString.h"
 | |
| #include "nsSystemInfo.h"
 | |
| #include "nsDirectoryServiceDefs.h"
 | |
| #include "nsXULAppAPI.h"
 | |
| #include "nsAppDirectoryServiceDefs.h"
 | |
| #include "mozJSComponentLoader.h"
 | |
| 
 | |
| #include "mozilla/ClearOnShutdown.h"
 | |
| #include "mozilla/StaticPtr.h"
 | |
| #include "mozilla/UniquePtr.h"
 | |
| 
 | |
| #include "OSFileConstants.h"
 | |
| #include "nsIOSFileConstantsService.h"
 | |
| #include "nsZipArchive.h"
 | |
| 
 | |
| #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
 | |
|     defined(__OpenBSD__)
 | |
| #  define __dd_fd dd_fd
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * This module defines the basic libc constants (error numbers, open modes,
 | |
|  * etc.) used by OS.File and possibly other OS-bound JavaScript libraries.
 | |
|  */
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| StaticRefPtr<OSFileConstantsService> gInstance;
 | |
| 
 | |
| }  // anonymous namespace
 | |
| 
 | |
| struct OSFileConstantsService::Paths {
 | |
|   /**
 | |
|    * The name of the directory holding all the libraries (libxpcom, libnss,
 | |
|    * etc.)
 | |
|    */
 | |
|   nsString libDir;
 | |
|   nsString tmpDir;
 | |
|   nsString profileDir;
 | |
|   nsString localProfileDir;
 | |
| 
 | |
|   Paths() {
 | |
|     libDir.SetIsVoid(true);
 | |
|     tmpDir.SetIsVoid(true);
 | |
|     profileDir.SetIsVoid(true);
 | |
|     localProfileDir.SetIsVoid(true);
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Return the path to one of the special directories.
 | |
|  *
 | |
|  * @param aKey The key to the special directory (e.g. "TmpD", "ProfD", ...)
 | |
|  * @param aOutPath The path to the special directory. In case of error,
 | |
|  * the string is set to void.
 | |
|  */
 | |
| nsresult GetPathToSpecialDir(const char *aKey, nsString &aOutPath) {
 | |
|   nsCOMPtr<nsIFile> file;
 | |
|   nsresult rv = NS_GetSpecialDirectory(aKey, getter_AddRefs(file));
 | |
|   if (NS_FAILED(rv) || !file) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   return file->GetPath(aOutPath);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * In some cases, OSFileConstants may be instantiated before the
 | |
|  * profile is setup. In such cases, |OS.Constants.Path.profileDir| and
 | |
|  * |OS.Constants.Path.localProfileDir| are undefined. However, we want
 | |
|  * to ensure that this does not break existing code, so that future
 | |
|  * workers spawned after the profile is setup have these constants.
 | |
|  *
 | |
|  * For this purpose, we register an observer to set |mPaths->profileDir|
 | |
|  * and |mPaths->localProfileDir| once the profile is setup.
 | |
|  */
 | |
| NS_IMETHODIMP
 | |
| OSFileConstantsService::Observe(nsISupports *, const char *aTopic,
 | |
|                                 const char16_t *) {
 | |
|   if (!mInitialized) {
 | |
|     // Initialization has not taken place, something is wrong,
 | |
|     // don't make things worse.
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   nsresult rv =
 | |
|       GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, mPaths->profileDir);
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
|   rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR,
 | |
|                            mPaths->localProfileDir);
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Perform the part of initialization that can only be
 | |
|  * executed on the main thread.
 | |
|  */
 | |
| nsresult OSFileConstantsService::InitOSFileConstants() {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
|   if (mInitialized) {
 | |
|     return NS_OK;
 | |
|   }
 | |
| 
 | |
|   UniquePtr<Paths> paths(new Paths);
 | |
| 
 | |
|   // Initialize paths->libDir
 | |
|   nsCOMPtr<nsIFile> file;
 | |
|   nsresult rv =
 | |
|       NS_GetSpecialDirectory(NS_XPCOM_LIBRARY_FILE, getter_AddRefs(file));
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIFile> libDir;
 | |
|   rv = file->GetParent(getter_AddRefs(libDir));
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   rv = libDir->GetPath(paths->libDir);
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   // Setup profileDir and localProfileDir immediately if possible (we
 | |
|   // assume that NS_APP_USER_PROFILE_50_DIR and
 | |
|   // NS_APP_USER_PROFILE_LOCAL_50_DIR are set simultaneously)
 | |
|   rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir);
 | |
|   if (NS_SUCCEEDED(rv)) {
 | |
|     rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR,
 | |
|                              paths->localProfileDir);
 | |
|   }
 | |
| 
 | |
|   // Otherwise, delay setup of profileDir/localProfileDir until they
 | |
|   // become available.
 | |
|   if (NS_FAILED(rv)) {
 | |
|     nsCOMPtr<nsIObserverService> obsService =
 | |
|         do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
 | |
|     if (NS_FAILED(rv)) {
 | |
|       return rv;
 | |
|     }
 | |
|     rv = obsService->AddObserver(this, "profile-do-change", false);
 | |
|     if (NS_FAILED(rv)) {
 | |
|       return rv;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir);
 | |
| 
 | |
|   mPaths = std::move(paths);
 | |
| 
 | |
|   // Get the umask from the system-info service.
 | |
|   // The property will always be present, but it will be zero on
 | |
|   // non-Unix systems.
 | |
|   // nsSystemInfo::gUserUmask is initialized by NS_InitXPCOM2 so we don't need
 | |
|   // to initialize the service.
 | |
|   mUserUmask = nsSystemInfo::gUserUmask;
 | |
| 
 | |
|   mInitialized = true;
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Define a simple read-only property holding an integer.
 | |
|  *
 | |
|  * @param name The name of the constant. Used both as the JS name for the
 | |
|  * constant and to access its value. Must be defined.
 | |
|  *
 | |
|  * Produces a |ConstantSpec|.
 | |
|  */
 | |
| #define INT_CONSTANT(name) \
 | |
|   { #name, JS::Int32Value(name) }
 | |
| 
 | |
| /**
 | |
|  * Define a simple read-only property holding an unsigned integer.
 | |
|  *
 | |
|  * @param name The name of the constant. Used both as the JS name for the
 | |
|  * constant and to access its value. Must be defined.
 | |
|  *
 | |
|  * Produces a |ConstantSpec|.
 | |
|  */
 | |
| #define UINT_CONSTANT(name) \
 | |
|   { #name, JS::NumberValue(name) }
 | |
| 
 | |
| /**
 | |
|  * End marker for ConstantSpec
 | |
|  */
 | |
| #define PROP_END \
 | |
|   { nullptr, JS::UndefinedValue() }
 | |
| 
 | |
| // Define missing constants for Android
 | |
| #if !defined(S_IRGRP)
 | |
| #  define S_IXOTH 0001
 | |
| #  define S_IWOTH 0002
 | |
| #  define S_IROTH 0004
 | |
| #  define S_IRWXO 0007
 | |
| #  define S_IXGRP 0010
 | |
| #  define S_IWGRP 0020
 | |
| #  define S_IRGRP 0040
 | |
| #  define S_IRWXG 0070
 | |
| #  define S_IXUSR 0100
 | |
| #  define S_IWUSR 0200
 | |
| #  define S_IRUSR 0400
 | |
| #  define S_IRWXU 0700
 | |
| #endif  // !defined(S_IRGRP)
 | |
| 
 | |
| /**
 | |
|  * The properties defined in libc.
 | |
|  *
 | |
|  * If you extend this list of properties, please
 | |
|  * separate categories ("errors", "open", etc.),
 | |
|  * keep properties organized by alphabetical order
 | |
|  * and #ifdef-away properties that are not portable.
 | |
|  */
 | |
| static const dom::ConstantSpec gLibcProperties[] = {
 | |
|     // Arguments for open
 | |
|     INT_CONSTANT(O_APPEND),
 | |
| #if defined(O_CLOEXEC)
 | |
|     INT_CONSTANT(O_CLOEXEC),
 | |
| #endif  // defined(O_CLOEXEC)
 | |
|     INT_CONSTANT(O_CREAT),
 | |
| #if defined(O_DIRECTORY)
 | |
|     INT_CONSTANT(O_DIRECTORY),
 | |
| #endif  // defined(O_DIRECTORY)
 | |
| #if defined(O_EVTONLY)
 | |
|     INT_CONSTANT(O_EVTONLY),
 | |
| #endif  // defined(O_EVTONLY)
 | |
|     INT_CONSTANT(O_EXCL),
 | |
| #if defined(O_EXLOCK)
 | |
|     INT_CONSTANT(O_EXLOCK),
 | |
| #endif  // defined(O_EXLOCK)
 | |
| #if defined(O_LARGEFILE)
 | |
|     INT_CONSTANT(O_LARGEFILE),
 | |
| #endif  // defined(O_LARGEFILE)
 | |
| #if defined(O_NOFOLLOW)
 | |
|     INT_CONSTANT(O_NOFOLLOW),
 | |
| #endif  // defined(O_NOFOLLOW)
 | |
| #if defined(O_NONBLOCK)
 | |
|     INT_CONSTANT(O_NONBLOCK),
 | |
| #endif  // defined(O_NONBLOCK)
 | |
|     INT_CONSTANT(O_RDONLY),
 | |
|     INT_CONSTANT(O_RDWR),
 | |
| #if defined(O_RSYNC)
 | |
|     INT_CONSTANT(O_RSYNC),
 | |
| #endif  // defined(O_RSYNC)
 | |
| #if defined(O_SHLOCK)
 | |
|     INT_CONSTANT(O_SHLOCK),
 | |
| #endif  // defined(O_SHLOCK)
 | |
| #if defined(O_SYMLINK)
 | |
|     INT_CONSTANT(O_SYMLINK),
 | |
| #endif  // defined(O_SYMLINK)
 | |
| #if defined(O_SYNC)
 | |
|     INT_CONSTANT(O_SYNC),
 | |
| #endif  // defined(O_SYNC)
 | |
|     INT_CONSTANT(O_TRUNC),
 | |
|     INT_CONSTANT(O_WRONLY),
 | |
| 
 | |
| #if defined(FD_CLOEXEC)
 | |
|     INT_CONSTANT(FD_CLOEXEC),
 | |
| #endif  // defined(FD_CLOEXEC)
 | |
| 
 | |
| #if defined(AT_EACCESS)
 | |
|     INT_CONSTANT(AT_EACCESS),
 | |
| #endif  // defined(AT_EACCESS)
 | |
| #if defined(AT_FDCWD)
 | |
|     INT_CONSTANT(AT_FDCWD),
 | |
| #endif  // defined(AT_FDCWD)
 | |
| #if defined(AT_SYMLINK_NOFOLLOW)
 | |
|     INT_CONSTANT(AT_SYMLINK_NOFOLLOW),
 | |
| #endif  // defined(AT_SYMLINK_NOFOLLOW)
 | |
| 
 | |
| #if defined(POSIX_FADV_SEQUENTIAL)
 | |
|     INT_CONSTANT(POSIX_FADV_SEQUENTIAL),
 | |
| #endif  // defined(POSIX_FADV_SEQUENTIAL)
 | |
| 
 | |
| // access
 | |
| #if defined(F_OK)
 | |
|     INT_CONSTANT(F_OK),
 | |
|     INT_CONSTANT(R_OK),
 | |
|     INT_CONSTANT(W_OK),
 | |
|     INT_CONSTANT(X_OK),
 | |
| #endif  // defined(F_OK)
 | |
| 
 | |
|     // modes
 | |
|     INT_CONSTANT(S_IRGRP),
 | |
|     INT_CONSTANT(S_IROTH),
 | |
|     INT_CONSTANT(S_IRUSR),
 | |
|     INT_CONSTANT(S_IRWXG),
 | |
|     INT_CONSTANT(S_IRWXO),
 | |
|     INT_CONSTANT(S_IRWXU),
 | |
|     INT_CONSTANT(S_IWGRP),
 | |
|     INT_CONSTANT(S_IWOTH),
 | |
|     INT_CONSTANT(S_IWUSR),
 | |
|     INT_CONSTANT(S_IXOTH),
 | |
|     INT_CONSTANT(S_IXGRP),
 | |
|     INT_CONSTANT(S_IXUSR),
 | |
| 
 | |
|     // seek
 | |
|     INT_CONSTANT(SEEK_CUR),
 | |
|     INT_CONSTANT(SEEK_END),
 | |
|     INT_CONSTANT(SEEK_SET),
 | |
| 
 | |
| #if defined(XP_UNIX)
 | |
|     // poll
 | |
|     INT_CONSTANT(POLLERR),
 | |
|     INT_CONSTANT(POLLHUP),
 | |
|     INT_CONSTANT(POLLIN),
 | |
|     INT_CONSTANT(POLLNVAL),
 | |
|     INT_CONSTANT(POLLOUT),
 | |
| 
 | |
| // wait
 | |
| #  if defined(WNOHANG)
 | |
|     INT_CONSTANT(WNOHANG),
 | |
| #  endif  // defined(WNOHANG)
 | |
| 
 | |
|     // fcntl command values
 | |
|     INT_CONSTANT(F_GETLK),
 | |
|     INT_CONSTANT(F_SETFD),
 | |
|     INT_CONSTANT(F_SETFL),
 | |
|     INT_CONSTANT(F_SETLK),
 | |
|     INT_CONSTANT(F_SETLKW),
 | |
| 
 | |
|     // flock type values
 | |
|     INT_CONSTANT(F_RDLCK),
 | |
|     INT_CONSTANT(F_WRLCK),
 | |
|     INT_CONSTANT(F_UNLCK),
 | |
| 
 | |
| // splice
 | |
| #  if defined(SPLICE_F_MOVE)
 | |
|     INT_CONSTANT(SPLICE_F_MOVE),
 | |
| #  endif  // defined(SPLICE_F_MOVE)
 | |
| #  if defined(SPLICE_F_NONBLOCK)
 | |
|     INT_CONSTANT(SPLICE_F_NONBLOCK),
 | |
| #  endif  // defined(SPLICE_F_NONBLOCK)
 | |
| #  if defined(SPLICE_F_MORE)
 | |
|     INT_CONSTANT(SPLICE_F_MORE),
 | |
| #  endif  // defined(SPLICE_F_MORE)
 | |
| #  if defined(SPLICE_F_GIFT)
 | |
|     INT_CONSTANT(SPLICE_F_GIFT),
 | |
| #  endif  // defined(SPLICE_F_GIFT)
 | |
| #endif    // defined(XP_UNIX)
 | |
| // copyfile
 | |
| #if defined(COPYFILE_DATA)
 | |
|     INT_CONSTANT(COPYFILE_DATA),
 | |
|     INT_CONSTANT(COPYFILE_EXCL),
 | |
|     INT_CONSTANT(COPYFILE_XATTR),
 | |
|     INT_CONSTANT(COPYFILE_STAT),
 | |
|     INT_CONSTANT(COPYFILE_ACL),
 | |
|     INT_CONSTANT(COPYFILE_MOVE),
 | |
| #endif  // defined(COPYFILE_DATA)
 | |
| 
 | |
|     // error values
 | |
|     INT_CONSTANT(EACCES),
 | |
|     INT_CONSTANT(EAGAIN),
 | |
|     INT_CONSTANT(EBADF),
 | |
|     INT_CONSTANT(EEXIST),
 | |
|     INT_CONSTANT(EFAULT),
 | |
|     INT_CONSTANT(EFBIG),
 | |
|     INT_CONSTANT(EINVAL),
 | |
|     INT_CONSTANT(EINTR),
 | |
|     INT_CONSTANT(EIO),
 | |
|     INT_CONSTANT(EISDIR),
 | |
| #if defined(ELOOP)  // not defined with VC9
 | |
|     INT_CONSTANT(ELOOP),
 | |
| #endif  // defined(ELOOP)
 | |
|     INT_CONSTANT(EMFILE),
 | |
|     INT_CONSTANT(ENAMETOOLONG),
 | |
|     INT_CONSTANT(ENFILE),
 | |
|     INT_CONSTANT(ENOENT),
 | |
|     INT_CONSTANT(ENOMEM),
 | |
|     INT_CONSTANT(ENOSPC),
 | |
|     INT_CONSTANT(ENOTDIR),
 | |
|     INT_CONSTANT(ENXIO),
 | |
| #if defined(EOPNOTSUPP)  // not defined with VC 9
 | |
|     INT_CONSTANT(EOPNOTSUPP),
 | |
| #endif                  // defined(EOPNOTSUPP)
 | |
| #if defined(EOVERFLOW)  // not defined with VC 9
 | |
|     INT_CONSTANT(EOVERFLOW),
 | |
| #endif  // defined(EOVERFLOW)
 | |
|     INT_CONSTANT(EPERM),
 | |
|     INT_CONSTANT(ERANGE),
 | |
| #if defined(ETIMEDOUT)  // not defined with VC 9
 | |
|     INT_CONSTANT(ETIMEDOUT),
 | |
| #endif                    // defined(ETIMEDOUT)
 | |
| #if defined(EWOULDBLOCK)  // not defined with VC 9
 | |
|     INT_CONSTANT(EWOULDBLOCK),
 | |
| #endif  // defined(EWOULDBLOCK)
 | |
|     INT_CONSTANT(EXDEV),
 | |
| 
 | |
| #if defined(DT_UNKNOWN)
 | |
|     // Constants for |readdir|
 | |
|     INT_CONSTANT(DT_UNKNOWN),
 | |
|     INT_CONSTANT(DT_FIFO),
 | |
|     INT_CONSTANT(DT_CHR),
 | |
|     INT_CONSTANT(DT_DIR),
 | |
|     INT_CONSTANT(DT_BLK),
 | |
|     INT_CONSTANT(DT_REG),
 | |
|     INT_CONSTANT(DT_LNK),
 | |
|     INT_CONSTANT(DT_SOCK),
 | |
| #endif  // defined(DT_UNKNOWN)
 | |
| 
 | |
| #if defined(S_IFIFO)
 | |
|     // Constants for |stat|
 | |
|     INT_CONSTANT(S_IFMT),
 | |
|     INT_CONSTANT(S_IFIFO),
 | |
|     INT_CONSTANT(S_IFCHR),
 | |
|     INT_CONSTANT(S_IFDIR),
 | |
|     INT_CONSTANT(S_IFBLK),
 | |
|     INT_CONSTANT(S_IFREG),
 | |
|     INT_CONSTANT(S_IFLNK),
 | |
|     INT_CONSTANT(S_IFSOCK),
 | |
| #endif  // defined(S_IFIFO)
 | |
| 
 | |
|     INT_CONSTANT(PATH_MAX),
 | |
| 
 | |
| // Constants used to define data structures
 | |
| //
 | |
| // Many data structures have different fields/sizes/etc. on
 | |
| // various OSes / versions of the same OS / platforms. For these
 | |
| // data structures, we need to compute and export from C the size
 | |
| // and, if necessary, the offset of fields, so as to be able to
 | |
| // define the structure in JS.
 | |
| 
 | |
| #if defined(XP_UNIX)
 | |
|     // The size of |mode_t|.
 | |
|     {"OSFILE_SIZEOF_MODE_T", JS::Int32Value(sizeof(mode_t))},
 | |
| 
 | |
|     // The size of |gid_t|.
 | |
|     {"OSFILE_SIZEOF_GID_T", JS::Int32Value(sizeof(gid_t))},
 | |
| 
 | |
|     // The size of |uid_t|.
 | |
|     {"OSFILE_SIZEOF_UID_T", JS::Int32Value(sizeof(uid_t))},
 | |
| 
 | |
|     // The size of |time_t|.
 | |
|     {"OSFILE_SIZEOF_TIME_T", JS::Int32Value(sizeof(time_t))},
 | |
| 
 | |
|     // The size of |fsblkcnt_t|.
 | |
|     {"OSFILE_SIZEOF_FSBLKCNT_T", JS::Int32Value(sizeof(fsblkcnt_t))},
 | |
| 
 | |
| #  if !defined(ANDROID)
 | |
|     // The size of |posix_spawn_file_actions_t|.
 | |
|     {"OSFILE_SIZEOF_POSIX_SPAWN_FILE_ACTIONS_T",
 | |
|      JS::Int32Value(sizeof(posix_spawn_file_actions_t))},
 | |
| #  endif  // !defined(ANDROID)
 | |
| 
 | |
|     // Defining |dirent|.
 | |
|     // Size
 | |
|     {"OSFILE_SIZEOF_DIRENT", JS::Int32Value(sizeof(dirent))},
 | |
| 
 | |
| // Defining |flock|.
 | |
| #  if defined(XP_UNIX)
 | |
|     {"OSFILE_SIZEOF_FLOCK", JS::Int32Value(sizeof(struct flock))},
 | |
|     {"OSFILE_OFFSETOF_FLOCK_L_START",
 | |
|      JS::Int32Value(offsetof(struct flock, l_start))},
 | |
|     {"OSFILE_OFFSETOF_FLOCK_L_LEN",
 | |
|      JS::Int32Value(offsetof(struct flock, l_len))},
 | |
|     {"OSFILE_OFFSETOF_FLOCK_L_PID",
 | |
|      JS::Int32Value(offsetof(struct flock, l_pid))},
 | |
|     {"OSFILE_OFFSETOF_FLOCK_L_TYPE",
 | |
|      JS::Int32Value(offsetof(struct flock, l_type))},
 | |
|     {"OSFILE_OFFSETOF_FLOCK_L_WHENCE",
 | |
|      JS::Int32Value(offsetof(struct flock, l_whence))},
 | |
| #  endif  // defined(XP_UNIX)
 | |
|     // Offset of field |d_name|.
 | |
|     {"OSFILE_OFFSETOF_DIRENT_D_NAME",
 | |
|      JS::Int32Value(offsetof(struct dirent, d_name))},
 | |
|     // An upper bound to the length of field |d_name| of struct |dirent|.
 | |
|     // (may not be exact, depending on padding).
 | |
|     {"OSFILE_SIZEOF_DIRENT_D_NAME",
 | |
|      JS::Int32Value(sizeof(struct dirent) - offsetof(struct dirent, d_name))},
 | |
| 
 | |
|     // Defining |timeval|.
 | |
|     {"OSFILE_SIZEOF_TIMEVAL", JS::Int32Value(sizeof(struct timeval))},
 | |
|     {"OSFILE_OFFSETOF_TIMEVAL_TV_SEC",
 | |
|      JS::Int32Value(offsetof(struct timeval, tv_sec))},
 | |
|     {"OSFILE_OFFSETOF_TIMEVAL_TV_USEC",
 | |
|      JS::Int32Value(offsetof(struct timeval, tv_usec))},
 | |
| 
 | |
| #  if defined(DT_UNKNOWN)
 | |
|     // Position of field |d_type| in |dirent|
 | |
|     // Not strictly posix, but seems defined on all platforms
 | |
|     // except mingw32.
 | |
|     {"OSFILE_OFFSETOF_DIRENT_D_TYPE",
 | |
|      JS::Int32Value(offsetof(struct dirent, d_type))},
 | |
| #  endif  // defined(DT_UNKNOWN)
 | |
| 
 | |
| // Under MacOS X and BSDs, |dirfd| is a macro rather than a
 | |
| // function, so we need a little help to get it to work
 | |
| #  if defined(dirfd)
 | |
|     {"OSFILE_SIZEOF_DIR", JS::Int32Value(sizeof(DIR))},
 | |
| 
 | |
|     {"OSFILE_OFFSETOF_DIR_DD_FD", JS::Int32Value(offsetof(DIR, __dd_fd))},
 | |
| #  endif
 | |
| 
 | |
|     // Defining |stat|
 | |
| 
 | |
|     {"OSFILE_SIZEOF_STAT", JS::Int32Value(sizeof(struct stat))},
 | |
| 
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_MODE",
 | |
|      JS::Int32Value(offsetof(struct stat, st_mode))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_UID",
 | |
|      JS::Int32Value(offsetof(struct stat, st_uid))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_GID",
 | |
|      JS::Int32Value(offsetof(struct stat, st_gid))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_SIZE",
 | |
|      JS::Int32Value(offsetof(struct stat, st_size))},
 | |
| 
 | |
| #  if defined(HAVE_ST_ATIMESPEC)
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_ATIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_atimespec))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_MTIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_mtimespec))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_CTIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_ctimespec))},
 | |
| #  else
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_ATIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_atime))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_MTIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_mtime))},
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_CTIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_ctime))},
 | |
| #  endif  // defined(HAVE_ST_ATIME)
 | |
| 
 | |
| // Several OSes have a birthtime field. For the moment, supporting only Darwin.
 | |
| #  if defined(_DARWIN_FEATURE_64_BIT_INODE)
 | |
|     {"OSFILE_OFFSETOF_STAT_ST_BIRTHTIME",
 | |
|      JS::Int32Value(offsetof(struct stat, st_birthtime))},
 | |
| #  endif  // defined(_DARWIN_FEATURE_64_BIT_INODE)
 | |
| 
 | |
|     // Defining |statvfs|
 | |
| 
 | |
|     {"OSFILE_SIZEOF_STATVFS", JS::Int32Value(sizeof(struct statvfs))},
 | |
| 
 | |
|     {"OSFILE_OFFSETOF_STATVFS_F_FRSIZE",
 | |
|      JS::Int32Value(offsetof(struct statvfs, f_frsize))},
 | |
|     {"OSFILE_OFFSETOF_STATVFS_F_BAVAIL",
 | |
|      JS::Int32Value(offsetof(struct statvfs, f_bavail))},
 | |
| 
 | |
| #endif  // defined(XP_UNIX)
 | |
| 
 | |
| // System configuration
 | |
| 
 | |
| // Under MacOSX, to avoid using deprecated functions that do not
 | |
| // match the constants we define in this object (including
 | |
| // |sizeof|/|offsetof| stuff, but not only), for a number of
 | |
| // functions, we need to adapt the name of the symbols we are using,
 | |
| // whenever macro _DARWIN_FEATURE_64_BIT_INODE is set. We export
 | |
| // this value to be able to do so from JavaScript.
 | |
| #if defined(_DARWIN_FEATURE_64_BIT_INODE)
 | |
|     {"_DARWIN_FEATURE_64_BIT_INODE", JS::Int32Value(1)},
 | |
| #endif  // defined(_DARWIN_FEATURE_64_BIT_INODE)
 | |
| 
 | |
| // Similar feature for Linux
 | |
| #if defined(_STAT_VER)
 | |
|     INT_CONSTANT(_STAT_VER),
 | |
| #endif  // defined(_STAT_VER)
 | |
| 
 | |
|     PROP_END};
 | |
| 
 | |
| #if defined(XP_WIN)
 | |
| /**
 | |
|  * The properties defined in windows.h.
 | |
|  *
 | |
|  * If you extend this list of properties, please
 | |
|  * separate categories ("errors", "open", etc.),
 | |
|  * keep properties organized by alphabetical order
 | |
|  * and #ifdef-away properties that are not portable.
 | |
|  */
 | |
| static const dom::ConstantSpec gWinProperties[] = {
 | |
|     // FormatMessage flags
 | |
|     INT_CONSTANT(FORMAT_MESSAGE_FROM_SYSTEM),
 | |
|     INT_CONSTANT(FORMAT_MESSAGE_IGNORE_INSERTS),
 | |
| 
 | |
|     // The max length of paths
 | |
|     INT_CONSTANT(MAX_PATH),
 | |
| 
 | |
|     // CreateFile desired access
 | |
|     INT_CONSTANT(GENERIC_ALL),
 | |
|     INT_CONSTANT(GENERIC_EXECUTE),
 | |
|     INT_CONSTANT(GENERIC_READ),
 | |
|     INT_CONSTANT(GENERIC_WRITE),
 | |
| 
 | |
|     // CreateFile share mode
 | |
|     INT_CONSTANT(FILE_SHARE_DELETE),
 | |
|     INT_CONSTANT(FILE_SHARE_READ),
 | |
|     INT_CONSTANT(FILE_SHARE_WRITE),
 | |
| 
 | |
|     // CreateFile creation disposition
 | |
|     INT_CONSTANT(CREATE_ALWAYS),
 | |
|     INT_CONSTANT(CREATE_NEW),
 | |
|     INT_CONSTANT(OPEN_ALWAYS),
 | |
|     INT_CONSTANT(OPEN_EXISTING),
 | |
|     INT_CONSTANT(TRUNCATE_EXISTING),
 | |
| 
 | |
|     // CreateFile attributes
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_ARCHIVE),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_DIRECTORY),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_HIDDEN),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_NORMAL),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_READONLY),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_REPARSE_POINT),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_SYSTEM),
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_TEMPORARY),
 | |
|     INT_CONSTANT(FILE_FLAG_BACKUP_SEMANTICS),
 | |
| 
 | |
|     // CreateFile error constant
 | |
|     {"INVALID_HANDLE_VALUE", JS::Int32Value(INT_PTR(INVALID_HANDLE_VALUE))},
 | |
| 
 | |
|     // CreateFile flags
 | |
|     INT_CONSTANT(FILE_FLAG_DELETE_ON_CLOSE),
 | |
| 
 | |
|     // SetFilePointer methods
 | |
|     INT_CONSTANT(FILE_BEGIN),
 | |
|     INT_CONSTANT(FILE_CURRENT),
 | |
|     INT_CONSTANT(FILE_END),
 | |
| 
 | |
|     // SetFilePointer error constant
 | |
|     UINT_CONSTANT(INVALID_SET_FILE_POINTER),
 | |
| 
 | |
|     // File attributes
 | |
|     INT_CONSTANT(FILE_ATTRIBUTE_DIRECTORY),
 | |
| 
 | |
|     // MoveFile flags
 | |
|     INT_CONSTANT(MOVEFILE_COPY_ALLOWED),
 | |
|     INT_CONSTANT(MOVEFILE_REPLACE_EXISTING),
 | |
| 
 | |
|     // GetFileAttributes error constant
 | |
|     INT_CONSTANT(INVALID_FILE_ATTRIBUTES),
 | |
| 
 | |
|     // GetNamedSecurityInfo and SetNamedSecurityInfo constants
 | |
|     INT_CONSTANT(UNPROTECTED_DACL_SECURITY_INFORMATION),
 | |
|     INT_CONSTANT(SE_FILE_OBJECT),
 | |
|     INT_CONSTANT(DACL_SECURITY_INFORMATION),
 | |
| 
 | |
|     // Errors
 | |
|     INT_CONSTANT(ERROR_INVALID_HANDLE),
 | |
|     INT_CONSTANT(ERROR_ACCESS_DENIED),
 | |
|     INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
 | |
|     INT_CONSTANT(ERROR_FILE_EXISTS),
 | |
|     INT_CONSTANT(ERROR_ALREADY_EXISTS),
 | |
|     INT_CONSTANT(ERROR_FILE_NOT_FOUND),
 | |
|     INT_CONSTANT(ERROR_NO_MORE_FILES),
 | |
|     INT_CONSTANT(ERROR_PATH_NOT_FOUND),
 | |
|     INT_CONSTANT(ERROR_BAD_ARGUMENTS),
 | |
|     INT_CONSTANT(ERROR_SHARING_VIOLATION),
 | |
|     INT_CONSTANT(ERROR_NOT_SUPPORTED),
 | |
| 
 | |
|     PROP_END};
 | |
| #endif  // defined(XP_WIN)
 | |
| 
 | |
| /**
 | |
|  * Get a field of an object as an object.
 | |
|  *
 | |
|  * If the field does not exist, create it. If it exists but is not an
 | |
|  * object, throw a JS error.
 | |
|  */
 | |
| JSObject *GetOrCreateObjectProperty(JSContext *cx,
 | |
|                                     JS::Handle<JSObject *> aObject,
 | |
|                                     const char *aProperty) {
 | |
|   JS::Rooted<JS::Value> val(cx);
 | |
|   if (!JS_GetProperty(cx, aObject, aProperty, &val)) {
 | |
|     return nullptr;
 | |
|   }
 | |
|   if (!val.isUndefined()) {
 | |
|     if (val.isObject()) {
 | |
|       return &val.toObject();
 | |
|     }
 | |
| 
 | |
|     JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr,
 | |
|                               JSMSG_UNEXPECTED_TYPE, aProperty,
 | |
|                               "not an object");
 | |
|     return nullptr;
 | |
|   }
 | |
|   return JS_DefineObject(cx, aObject, aProperty, nullptr, JSPROP_ENUMERATE);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Set a property of an object from a nsString.
 | |
|  *
 | |
|  * If the nsString is void (i.e. IsVoid is true), do nothing.
 | |
|  */
 | |
| bool SetStringProperty(JSContext *cx, JS::Handle<JSObject *> aObject,
 | |
|                        const char *aProperty, const nsString aValue) {
 | |
|   if (aValue.IsVoid()) {
 | |
|     return true;
 | |
|   }
 | |
|   JSString *strValue = JS_NewUCStringCopyZ(cx, aValue.get());
 | |
|   NS_ENSURE_TRUE(strValue, false);
 | |
|   JS::Rooted<JS::Value> valValue(cx, JS::StringValue(strValue));
 | |
|   return JS_SetProperty(cx, aObject, aProperty, valValue);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Define OS-specific constants.
 | |
|  *
 | |
|  * This function creates or uses JS object |OS.Constants| to store
 | |
|  * all its constants.
 | |
|  */
 | |
| bool OSFileConstantsService::DefineOSFileConstants(
 | |
|     JSContext *aCx, JS::Handle<JSObject *> aGlobal) {
 | |
|   if (!mInitialized) {
 | |
|     JS_ReportErrorNumberASCII(aCx, js::GetErrorMessage, nullptr,
 | |
|                               JSMSG_CANT_OPEN, "OSFileConstants",
 | |
|                               "initialization has failed");
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   JS::Rooted<JSObject *> objOS(aCx);
 | |
|   if (!(objOS = GetOrCreateObjectProperty(aCx, aGlobal, "OS"))) {
 | |
|     return false;
 | |
|   }
 | |
|   JS::Rooted<JSObject *> objConstants(aCx);
 | |
|   if (!(objConstants = GetOrCreateObjectProperty(aCx, objOS, "Constants"))) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Build OS.Constants.libc
 | |
| 
 | |
|   JS::Rooted<JSObject *> objLibc(aCx);
 | |
|   if (!(objLibc = GetOrCreateObjectProperty(aCx, objConstants, "libc"))) {
 | |
|     return false;
 | |
|   }
 | |
|   if (!dom::DefineConstants(aCx, objLibc, gLibcProperties)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
| #if defined(XP_WIN)
 | |
|   // Build OS.Constants.Win
 | |
| 
 | |
|   JS::Rooted<JSObject *> objWin(aCx);
 | |
|   if (!(objWin = GetOrCreateObjectProperty(aCx, objConstants, "Win"))) {
 | |
|     return false;
 | |
|   }
 | |
|   if (!dom::DefineConstants(aCx, objWin, gWinProperties)) {
 | |
|     return false;
 | |
|   }
 | |
| #endif  // defined(XP_WIN)
 | |
| 
 | |
|   // Build OS.Constants.Sys
 | |
| 
 | |
|   JS::Rooted<JSObject *> objSys(aCx);
 | |
|   if (!(objSys = GetOrCreateObjectProperty(aCx, objConstants, "Sys"))) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   nsCOMPtr<nsIXULRuntime> runtime =
 | |
|       do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
 | |
|   if (runtime) {
 | |
|     nsAutoCString os;
 | |
|     DebugOnly<nsresult> rv = runtime->GetOS(os);
 | |
|     MOZ_ASSERT(NS_SUCCEEDED(rv));
 | |
| 
 | |
|     JSString *strVersion = JS_NewStringCopyZ(aCx, os.get());
 | |
|     if (!strVersion) {
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     JS::Rooted<JS::Value> valVersion(aCx, JS::StringValue(strVersion));
 | |
|     if (!JS_SetProperty(aCx, objSys, "Name", valVersion)) {
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #if defined(DEBUG)
 | |
|   JS::Rooted<JS::Value> valDebug(aCx, JS::TrueValue());
 | |
|   if (!JS_SetProperty(aCx, objSys, "DEBUG", valDebug)) {
 | |
|     return false;
 | |
|   }
 | |
| #endif
 | |
| 
 | |
| #if defined(HAVE_64BIT_BUILD)
 | |
|   JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(64));
 | |
| #else
 | |
|   JS::Rooted<JS::Value> valBits(aCx, JS::Int32Value(32));
 | |
| #endif  // defined (HAVE_64BIT_BUILD)
 | |
|   if (!JS_SetProperty(aCx, objSys, "bits", valBits)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (!JS_DefineProperty(
 | |
|           aCx, objSys, "umask", mUserUmask,
 | |
|           JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Build OS.Constants.Path
 | |
| 
 | |
|   JS::Rooted<JSObject *> objPath(aCx);
 | |
|   if (!(objPath = GetOrCreateObjectProperty(aCx, objConstants, "Path"))) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Locate libxul
 | |
|   // Note that we don't actually provide the full path, only the name of the
 | |
|   // library, which is sufficient to link to the library using js-ctypes.
 | |
| 
 | |
| #if defined(XP_MACOSX)
 | |
|   // Under MacOS X, for some reason, libxul is called simply "XUL",
 | |
|   // and we need to provide the full path.
 | |
|   nsAutoString libxul;
 | |
|   libxul.Append(mPaths->libDir);
 | |
|   libxul.AppendLiteral("/XUL");
 | |
| #else
 | |
|   // On other platforms, libxul is a library "xul" with regular
 | |
|   // library prefix/suffix.
 | |
|   nsAutoString libxul;
 | |
|   libxul.AppendLiteral(MOZ_DLL_PREFIX);
 | |
|   libxul.AppendLiteral("xul");
 | |
|   libxul.AppendLiteral(MOZ_DLL_SUFFIX);
 | |
| #endif  // defined(XP_MACOSX)
 | |
| 
 | |
|   if (!SetStringProperty(aCx, objPath, "libxul", libxul)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (!SetStringProperty(aCx, objPath, "libDir", mPaths->libDir)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   if (!SetStringProperty(aCx, objPath, "tmpDir", mPaths->tmpDir)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Configure profileDir only if it is available at this stage
 | |
|   if (!mPaths->profileDir.IsVoid() &&
 | |
|       !SetStringProperty(aCx, objPath, "profileDir", mPaths->profileDir)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // Configure localProfileDir only if it is available at this stage
 | |
|   if (!mPaths->localProfileDir.IsVoid() &&
 | |
|       !SetStringProperty(aCx, objPath, "localProfileDir",
 | |
|                          mPaths->localProfileDir)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   // sqlite3 is linked from different places depending on the platform
 | |
|   nsAutoString libsqlite3;
 | |
| #if defined(ANDROID)
 | |
|   // On Android, we use the system's libsqlite3
 | |
|   libsqlite3.AppendLiteral(MOZ_DLL_PREFIX);
 | |
|   libsqlite3.AppendLiteral("sqlite3");
 | |
|   libsqlite3.AppendLiteral(MOZ_DLL_SUFFIX);
 | |
| #elif defined(XP_WIN)
 | |
|   // On Windows, for some reason, this is part of nss3.dll
 | |
|   libsqlite3.AppendLiteral(MOZ_DLL_PREFIX);
 | |
|   libsqlite3.AppendLiteral("nss3");
 | |
|   libsqlite3.AppendLiteral(MOZ_DLL_SUFFIX);
 | |
| #else
 | |
|   // On other platforms, we link sqlite3 into libxul
 | |
|   libsqlite3 = libxul;
 | |
| #endif  // defined(ANDROID) || defined(XP_WIN)
 | |
| 
 | |
|   if (!SetStringProperty(aCx, objPath, "libsqlite3", libsqlite3)) {
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| NS_IMPL_ISUPPORTS(OSFileConstantsService, nsIOSFileConstantsService,
 | |
|                   nsIObserver)
 | |
| 
 | |
| /* static */
 | |
| already_AddRefed<OSFileConstantsService> OSFileConstantsService::GetOrCreate() {
 | |
|   if (!gInstance) {
 | |
|     MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|     RefPtr<OSFileConstantsService> service = new OSFileConstantsService();
 | |
|     nsresult rv = service->InitOSFileConstants();
 | |
|     if (NS_WARN_IF(NS_FAILED(rv))) {
 | |
|       return nullptr;
 | |
|     }
 | |
| 
 | |
|     gInstance = service.forget();
 | |
|     ClearOnShutdown(&gInstance);
 | |
|   }
 | |
| 
 | |
|   RefPtr<OSFileConstantsService> copy = gInstance;
 | |
|   return copy.forget();
 | |
| }
 | |
| 
 | |
| OSFileConstantsService::OSFileConstantsService()
 | |
|     : mInitialized(false), mUserUmask(0) {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| }
 | |
| 
 | |
| OSFileConstantsService::~OSFileConstantsService() {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| }
 | |
| 
 | |
| NS_IMETHODIMP
 | |
| OSFileConstantsService::Init(JSContext *aCx) {
 | |
|   MOZ_ASSERT(NS_IsMainThread());
 | |
| 
 | |
|   nsresult rv = InitOSFileConstants();
 | |
|   if (NS_FAILED(rv)) {
 | |
|     return rv;
 | |
|   }
 | |
| 
 | |
|   mozJSComponentLoader *loader = mozJSComponentLoader::Get();
 | |
|   JS::Rooted<JSObject *> targetObj(aCx);
 | |
|   loader->FindTargetObject(aCx, &targetObj);
 | |
| 
 | |
|   if (!DefineOSFileConstants(aCx, targetObj)) {
 | |
|     return NS_ERROR_FAILURE;
 | |
|   }
 | |
| 
 | |
|   return NS_OK;
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 |