LCOV - code coverage report
Current view: top level - dom/system - OSFileConstants.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 109 173 63.0 %
Date: 2017-07-14 16:53:18 Functions: 11 20 55.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13