dom/system/OSFileConstants.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial