|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 'use strict'; |
|
6 |
|
7 module.metadata = { |
|
8 "stability": "unstable" |
|
9 }; |
|
10 |
|
11 const { Cc, Ci, CC } = require('chrome'); |
|
12 const options = require('@loader/options'); |
|
13 const file = require('./io/file'); |
|
14 const runtime = require("./system/runtime"); |
|
15 |
|
16 const appStartup = Cc['@mozilla.org/toolkit/app-startup;1']. |
|
17 getService(Ci.nsIAppStartup); |
|
18 const appInfo = Cc["@mozilla.org/xre/app-info;1"]. |
|
19 getService(Ci.nsIXULAppInfo); |
|
20 const directoryService = Cc['@mozilla.org/file/directory_service;1']. |
|
21 getService(Ci.nsIProperties); |
|
22 |
|
23 const PR_WRONLY = parseInt("0x02"); |
|
24 const PR_CREATE_FILE = parseInt("0x08"); |
|
25 const PR_APPEND = parseInt("0x10"); |
|
26 const PR_TRUNCATE = parseInt("0x20"); |
|
27 |
|
28 function openFile(path, mode) { |
|
29 let file = Cc["@mozilla.org/file/local;1"]. |
|
30 createInstance(Ci.nsILocalFile); |
|
31 file.initWithPath(path); |
|
32 let stream = Cc["@mozilla.org/network/file-output-stream;1"]. |
|
33 createInstance(Ci.nsIFileOutputStream); |
|
34 stream.init(file, mode, -1, 0); |
|
35 return stream |
|
36 } |
|
37 |
|
38 const { eAttemptQuit: E_ATTEMPT, eForceQuit: E_FORCE } = appStartup; |
|
39 |
|
40 /** |
|
41 * Parsed JSON object that was passed via `cfx --static-args "{ foo: 'bar' }"` |
|
42 */ |
|
43 exports.staticArgs = options.staticArgs; |
|
44 |
|
45 /** |
|
46 * Environment variables. Environment variables are non-enumerable properties |
|
47 * of this object (key is name and value is value). |
|
48 */ |
|
49 exports.env = require('./system/environment').env; |
|
50 |
|
51 /** |
|
52 * Ends the process with the specified `code`. If omitted, exit uses the |
|
53 * 'success' code 0. To exit with failure use `1`. |
|
54 * TODO: Improve platform to actually quit with an exit code. |
|
55 */ |
|
56 let forcedExit = false; |
|
57 exports.exit = function exit(code) { |
|
58 if (forcedExit) { |
|
59 // a forced exit was already tried |
|
60 // NOTE: exit(0) is called twice sometimes (ex when using cfx testaddons) |
|
61 return; |
|
62 } |
|
63 |
|
64 // This is used by 'cfx' to find out exit code. |
|
65 if ('resultFile' in options && options.resultFile) { |
|
66 let mode = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE; |
|
67 let stream = openFile(options.resultFile, mode); |
|
68 let status = code ? 'FAIL' : 'OK'; |
|
69 stream.write(status, status.length); |
|
70 stream.flush(); |
|
71 stream.close(); |
|
72 } |
|
73 |
|
74 if (code == 0) { |
|
75 forcedExit = true; |
|
76 } |
|
77 appStartup.quit(code ? E_ATTEMPT : E_FORCE); |
|
78 }; |
|
79 |
|
80 // Adapter for nodejs's stdout & stderr: |
|
81 // http://nodejs.org/api/process.html#process_process_stdout |
|
82 let stdout = Object.freeze({ write: dump, end: dump }); |
|
83 exports.stdout = stdout; |
|
84 exports.stderr = stdout; |
|
85 |
|
86 /** |
|
87 * Returns a path of the system's or application's special directory / file |
|
88 * associated with a given `id`. For list of possible `id`s please see: |
|
89 * https://developer.mozilla.org/en-US/docs/Code_snippets/File_I_O#Getting_files_in_special_directories |
|
90 * http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsAppDirectoryServiceDefs.h |
|
91 * @example |
|
92 * |
|
93 * // get firefox profile path |
|
94 * let profilePath = require('system').pathFor('ProfD'); |
|
95 * // get OS temp files directory (/tmp) |
|
96 * let temps = require('system').pathFor('TmpD'); |
|
97 * // get OS desktop path for an active user (~/Desktop on linux |
|
98 * // or C:\Documents and Settings\username\Desktop on windows). |
|
99 * let desktopPath = require('system').pathFor('Desk'); |
|
100 */ |
|
101 exports.pathFor = function pathFor(id) { |
|
102 return directoryService.get(id, Ci.nsIFile).path; |
|
103 }; |
|
104 |
|
105 /** |
|
106 * What platform you're running on (all lower case string). |
|
107 * For possible values see: |
|
108 * https://developer.mozilla.org/en/OS_TARGET |
|
109 */ |
|
110 exports.platform = runtime.OS.toLowerCase(); |
|
111 |
|
112 const [, architecture, compiler] = runtime.XPCOMABI ? |
|
113 runtime.XPCOMABI.match(/^([^-]*)-(.*)$/) : |
|
114 [, null, null]; |
|
115 |
|
116 /** |
|
117 * What processor architecture you're running on: |
|
118 * `'arm', 'ia32', or 'x64'`. |
|
119 */ |
|
120 exports.architecture = architecture; |
|
121 |
|
122 /** |
|
123 * What compiler used for build: |
|
124 * `'msvc', 'n32', 'gcc2', 'gcc3', 'sunc', 'ibmc'...` |
|
125 */ |
|
126 exports.compiler = compiler; |
|
127 |
|
128 /** |
|
129 * The application's build ID/date, for example "2004051604". |
|
130 */ |
|
131 exports.build = appInfo.appBuildID; |
|
132 |
|
133 /** |
|
134 * The XUL application's UUID. |
|
135 * This has traditionally been in the form |
|
136 * `{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}` but for some applications it may |
|
137 * be: "appname@vendor.tld". |
|
138 */ |
|
139 exports.id = appInfo.ID; |
|
140 |
|
141 /** |
|
142 * The name of the application. |
|
143 */ |
|
144 exports.name = appInfo.name; |
|
145 |
|
146 /** |
|
147 * The XUL application's version, for example "0.8.0+" or "3.7a1pre". |
|
148 */ |
|
149 exports.version = appInfo.version; |
|
150 |
|
151 /** |
|
152 * XULRunner version. |
|
153 */ |
|
154 exports.platformVersion = appInfo.platformVersion; |
|
155 |
|
156 |
|
157 /** |
|
158 * The name of the application vendor, for example "Mozilla". |
|
159 */ |
|
160 exports.vendor = appInfo.vendor; |