Backed out changeset 81f210d3ad52 (bug 944451) for device image bustage.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 10 Feb 2014 10:17:41 -0500
changeset 167867 a4260bb263b6a2a244ed516ecbcd9b99ceb0369e
parent 167866 cf1cc24b68ef8357a7020c3beacd2c3bc97f843f
child 167868 8f50eb1030edcea37e96bfc5383fed31e97ec6a3
push id4976
push userryanvm@gmail.com
push dateMon, 10 Feb 2014 20:45:45 +0000
treeherderfx-team@8e5b70407721 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs944451
milestone30.0a1
backs out81f210d3ad52c0fe6f41a895444da1d91cb30b7a
Backed out changeset 81f210d3ad52 (bug 944451) for device image bustage.
b2g/build.mk
b2g/simulator/build_xpi.py
b2g/simulator/custom-prefs.js
b2g/simulator/custom-settings.json
b2g/simulator/icon.png
b2g/simulator/icon64.png
b2g/simulator/lib/main.js
b2g/simulator/lib/simulator-process.js
b2g/simulator/package-overload.json.in
b2g/simulator/package.json
b2g/simulator/packages/subprocess/README.md
b2g/simulator/packages/subprocess/lib/subprocess.js
b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js
b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js
b2g/simulator/packages/subprocess/package.json
b2g/simulator/packages/subprocess/tests/test-subprocess.js
configure.in
--- a/b2g/build.mk
+++ b/b2g/build.mk
@@ -1,22 +1,17 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
-
 installer: 
 	@$(MAKE) -C b2g/installer installer
 
 package:
 	@$(MAKE) -C b2g/installer
-#ifdef FXOS_SIMULATOR
-	$(PYTHON) $(srcdir)/b2g/simulator/build_xpi.py $(MOZ_PKG_PLATFORM)
-#endif
 
 install::
 	@echo 'B2G can't be installed directly.'
 	@exit 1
 
 upload::
 	@$(MAKE) -C b2g/installer upload
 
deleted file mode 100644
--- a/b2g/simulator/build_xpi.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Generate xpi for the simulator addon by:
-# - building a special gaia profile for it, as we need:
-#     * more languages, and,
-#     * less apps
-#   than b2g desktop's one
-# - retrieve usefull app version metadata from the build system
-# - finally, use addon sdk's cfx tool to build the addon xpi
-#   that ships:
-#     * a small firefox addon registering to the app manager
-#     * b2g desktop runtime
-#     * gaia profile
-
-import sys, os, re, subprocess
-from mozbuild.preprocessor import Preprocessor
-from mozbuild.base import MozbuildObject
-from mozbuild.util import ensureParentDir
-from zipfile import ZipFile
-from distutils.version import LooseVersion
-
-ftp_root_path = "/pub/mozilla.org/labs/fxos-simulator"
-UPDATE_LINK = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/%(xpi_name)s"
-UPDATE_URL = "https://ftp.mozilla.org" + ftp_root_path + "/%(update_path)s/update.rdf"
-XPI_NAME = "fxos-simulator-%(version)s-%(platform)s.xpi"
-
-class GaiaBuilder(object):
-    def __init__(self, build, gaia_path):
-        self.build = build
-        self.gaia_path = gaia_path
-
-    def clean(self):
-        self.build._run_make(target="clean", directory=self.gaia_path)
-
-    def profile(self, env):
-        self.build._run_make(target="profile", directory=self.gaia_path, num_jobs=1, silent=False, append_env=env)
-
-    def override_prefs(self, srcfile):
-        # Note that each time we call `make profile` in gaia, a fresh new pref file is created
-        # cat srcfile >> profile/user.js
-        with open(os.path.join(self.gaia_path, "profile", "user.js"), "a") as userJs:
-            userJs.write(open(srcfile).read())
-
-def process_package_overload(src, dst, version, app_buildid):
-    ensureParentDir(dst)
-    # First replace numeric version like '1.3'
-    # Then replace with 'slashed' version like '1_4'
-    # Finally set the full length addon version like 1.3.20131230
-    defines = {
-        "NUM_VERSION": version,
-        "SLASH_VERSION": version.replace(".", "_"),
-        "FULL_VERSION": ("%s.%s" % (version, app_buildid))
-    }
-    pp = Preprocessor(defines=defines)
-    pp.do_filter("substitution")
-    with open(dst, "w") as output:
-        with open(src, "r") as input:
-            pp.processFile(input=input, output=output)
-
-def add_dir_to_zip(zip, top, pathInZip, blacklist=()):
-    zf = ZipFile(zip, "a")
-    for dirpath, subdirs, files in os.walk(top):
-        dir_relpath = os.path.relpath(dirpath, top)
-        if dir_relpath.startswith(blacklist):
-            continue
-        zf.write(dirpath, os.path.join(pathInZip, dir_relpath))
-        for filename in files:
-            relpath = os.path.join(dir_relpath, filename)
-            if relpath in blacklist:
-                continue
-            zf.write(os.path.join(dirpath, filename),
-                     os.path.join(pathInZip, relpath))
-    zf.close()
-
-def main(platform):
-    build = MozbuildObject.from_environment()
-    topsrcdir = build.topsrcdir
-    distdir = build.distdir
-
-    srcdir = os.path.join(topsrcdir, "b2g", "simulator")
-
-    app_buildid = open(os.path.join(build.topobjdir, "config", "buildid")).read().strip()
-
-    # The simulator uses a shorter version string,
-    # it only keeps the major version digits A.B
-    # whereas MOZ_B2G_VERSION is A.B.C.D
-    b2g_version = build.config_environment.defines["MOZ_B2G_VERSION"].replace('"', '')
-    version = ".".join(str(n) for n in LooseVersion(b2g_version).version[0:2])
-
-    # Build a gaia profile specific to the simulator in order to:
-    # - disable the FTU
-    # - set custom prefs to enable devtools debugger server
-    # - set custom settings to disable lockscreen and screen timeout
-    # - only ship production apps
-    gaia_path = build.config_environment.substs["GAIADIR"]
-    builder = GaiaBuilder(build, gaia_path)
-    builder.clean()
-    env = {
-      "NOFTU": "1",
-      "GAIA_APP_TARGET": "production",
-      "SETTINGS_PATH": os.path.join(srcdir, "custom-settings.json")
-    }
-    builder.profile(env)
-    builder.override_prefs(os.path.join(srcdir, "custom-prefs.js"))
-
-    # Substitute version strings in the package manifest overload file
-    manifest_overload = os.path.join(build.topobjdir, "b2g", "simulator", "package-overload.json")
-    process_package_overload(os.path.join(srcdir, "package-overload.json.in"),
-                             manifest_overload,
-                             version,
-                             app_buildid)
-
-    # Build the simulator addon xpi
-    xpi_name = XPI_NAME % {"version": version, "platform": platform}
-    xpi_path = os.path.join(distdir, xpi_name)
-
-    update_path = "%s/%s" % (version, platform)
-    update_link = UPDATE_LINK % {"update_path": update_path, "xpi_name": xpi_name}
-    update_url = UPDATE_URL % {"update_path": update_path}
-    subprocess.check_call([
-      build.virtualenv_manager.python_path, os.path.join(topsrcdir, "addon-sdk", "source", "bin", "cfx"), "xpi", \
-      "--pkgdir", srcdir, \
-      "--manifest-overload", manifest_overload, \
-      "--strip-sdk", \
-      "--update-link", update_link, \
-      "--update-url", update_url, \
-      "--static-args", "{\"label\": \"Firefox OS %s\"}" % version, \
-      "--output-file", xpi_path \
-    ])
-
-    # Ship b2g-desktop, but prevent its gaia profile to be shipped in the xpi
-    add_dir_to_zip(xpi_path, os.path.join(distdir, "b2g"), "b2g", ("gaia"))
-    # Then ship our own gaia profile
-    add_dir_to_zip(xpi_path, os.path.join(gaia_path, "profile"), "profile")
-
-if __name__ == '__main__':
-    if 2 != len(sys.argv):
-        print("""Usage:
-  python {0} MOZ_PKG_PLATFORM
-""".format(sys.argv[0]))
-        sys.exit(1)
-    main(*sys.argv[1:])
-
deleted file mode 100644
--- a/b2g/simulator/custom-prefs.js
+++ /dev/null
@@ -1,2 +0,0 @@
-user_pref("devtools.debugger.prompt-connection", false);
-user_pref("devtools.debugger.forbid-certified-apps", false);
deleted file mode 100644
--- a/b2g/simulator/custom-settings.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "debugger.remote-mode": "adb-devtools",
-  "screen.timeout": 0,
-  "lockscreen.enabled": false,
-  "lockscreen.locked": false
-}
deleted file mode 100644
index c4307fc8418436bb6b2fd3a6afc702c2db28aa77..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 275cd04a5eae3f727c1272cb71d3090dbcecd732..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
--- a/b2g/simulator/lib/main.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-const { Cc, Ci, Cu } = require("chrome");
-
-const { SimulatorProcess } = require("./simulator-process");
-const Promise = require("sdk/core/promise");
-const Self = require("sdk/self");
-const System = require("sdk/system");
-const { Simulator } = Cu.import("resource://gre/modules/devtools/Simulator.jsm");
-
-let process;
-
-function launch({ port }) {
-  // Close already opened simulation
-  if (process) {
-    return close().then(launch.bind(null, { port: port }));
-  }
-
-  process = SimulatorProcess();
-  process.remoteDebuggerPort = port;
-  process.run();
-
-  return Promise.resolve();
-}
-
-function close() {
-  if (!process) {
-    return Promise.resolve();
-  }
-  let p = process;
-  process = null;
-  return p.kill();
-}
-
-
-// Load data generated at build time that
-// expose various information about the runtime we ship
-let appinfo = System.staticArgs;
-
-Simulator.register(appinfo.label, {
-  appinfo: appinfo,
-  launch: launch,
-  close: close
-});
-
-require("sdk/system/unload").when(function () {
-  Simulator.unregister(appinfo.label);
-  close();
-});
deleted file mode 100644
--- a/b2g/simulator/lib/simulator-process.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-'use strict';
-
-const { Cc, Ci, Cu, ChromeWorker } = require("chrome");
-
-Cu.import("resource://gre/modules/Services.jsm");
-
-const { EventTarget } = require("sdk/event/target");
-const { emit, off } = require("sdk/event/core");
-const { Class } = require("sdk/core/heritage");
-const Environment = require("sdk/system/environment").env;
-const Runtime = require("sdk/system/runtime");
-const Self = require("sdk/self");
-const URL = require("sdk/url");
-const Subprocess = require("subprocess");
-const Promise = require("sdk/core/promise");
-
-const { rootURI: ROOT_URI } = require('@loader/options');
-const PROFILE_URL = ROOT_URI + "profile/";
-const BIN_URL = ROOT_URI + "b2g/";
-
-// Log subprocess error and debug messages to the console.  This logs messages
-// for all consumers of the API.  We trim the messages because they sometimes
-// have trailing newlines.  And note that registerLogHandler actually registers
-// an error handler, despite its name.
-Subprocess.registerLogHandler(
-  function(s) console.error("subprocess: " + s.trim())
-);
-Subprocess.registerDebugHandler(
-  function(s) console.debug("subprocess: " + s.trim())
-);
-
-exports.SimulatorProcess = Class({
-  extends: EventTarget,
-  initialize: function initialize(options) {
-    EventTarget.prototype.initialize.call(this, options);
-
-    this.on("stdout", function onStdout(data) console.log(data.trim()));
-    this.on("stderr", function onStderr(data) console.error(data.trim()));
-  },
-
-  // check if b2g is running
-  get isRunning() !!this.process,
-
-  /**
-   * Start the process and connect the debugger client.
-   */
-  run: function() {
-    // kill before start if already running
-    if (this.process != null) {
-      this.process
-          .kill()
-          .then(this.run.bind(this));
-      return;
-    }
-
-    // resolve b2g binaries path (raise exception if not found)
-    let b2gExecutable = this.b2gExecutable;
-
-    this.once("stdout", function () {
-      if (Runtime.OS == "Darwin") {
-          console.debug("WORKAROUND run osascript to show b2g-desktop window"+
-                        " on Runtime.OS=='Darwin'");
-        // Escape double quotes and escape characters for use in AppleScript.
-        let path = b2gExecutable.path
-          .replace(/\\/g, "\\\\").replace(/\"/g, '\\"');
-
-        Subprocess.call({
-          command: "/usr/bin/osascript",
-          arguments: ["-e", 'tell application "' + path + '" to activate'],
-        });
-      }
-    });
-
-    let environment;
-    if (Runtime.OS == "Linux") {
-      environment = ["TMPDIR=" + Services.dirsvc.get("TmpD",Ci.nsIFile).path];
-      if ("DISPLAY" in Environment) {
-        environment.push("DISPLAY=" + Environment.DISPLAY);
-      }
-    }
-
-    // spawn a b2g instance
-    this.process = Subprocess.call({
-      command: b2gExecutable,
-      arguments: this.b2gArguments,
-      environment: environment,
-
-      // emit stdout event
-      stdout: (function(data) {
-        emit(this, "stdout", data);
-      }).bind(this),
-
-      // emit stderr event
-      stderr: (function(data) {
-        emit(this, "stderr", data);
-      }).bind(this),
-
-      // on b2g instance exit, reset tracked process, remoteDebuggerPort and
-      // shuttingDown flag, then finally emit an exit event
-      done: (function(result) {
-        console.log(this.b2gFilename + " terminated with " + result.exitCode);
-        this.process = null;
-        emit(this, "exit", result.exitCode);
-      }).bind(this)
-    });
-  },
-
-  // request a b2g instance kill
-  kill: function() {
-    let deferred = Promise.defer();
-    if (this.process) {
-      this.once("exit", (exitCode) => {
-        this.shuttingDown = false;
-        deferred.resolve(exitCode);
-      });
-      if (!this.shuttingDown) {
-        this.shuttingDown = true;
-        emit(this, "kill", null);
-        this.process.kill();
-      }
-      return deferred.promise;
-    } else {
-      return Promise.resolve(undefined);
-    }
-  },
-
-  // compute current b2g filename
-  get b2gFilename() {
-    return this._executable ? this._executableFilename : "B2G";
-  },
-
-  // compute current b2g file handle
-  get b2gExecutable() {
-    if (this._executable) return this._executable;
-
-    let bin = URL.toFilename(BIN_URL);
-    let executables = {
-      WINNT: "b2g-bin.exe",
-      Darwin: "Contents/MacOS/b2g-bin",
-      Linux: "b2g-bin",
-    };
-
-    console.log("bin url: "+bin+"/"+executables[Runtime.OS]);
-    let path = bin + "/" + executables[Runtime.OS];
-
-    let executable = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
-    executable.initWithPath(path);
-
-    if (!executable.exists()) {
-      // B2G binaries not found
-      throw Error("b2g-desktop Executable not found.");
-    }
-
-    this._executable = executable;
-    this._executableFilename = "b2g-bin";
-
-    return executable;
-  },
-
-  // compute b2g CLI arguments
-  get b2gArguments() {
-    let args = [];
-
-    let profile = URL.toFilename(PROFILE_URL);
-    args.push("-profile", profile);
-    Cu.reportError(profile);
-
-    // NOTE: push dbgport option on the b2g-desktop commandline
-    args.push("-dbgport", "" + this.remoteDebuggerPort);
-
-    // Ignore eventual zombie instances of b2g that are left over
-    args.push("-no-remote");
-
-    return args;
-  },
-});
-
deleted file mode 100644
--- a/b2g/simulator/package-overload.json.in
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "id": "fxos_@SLASH_VERSION@_simulator@mozilla.org",
-  "name": "fxos_@SLASH_VERSION@_simulator",
-  "version": "@FULL_VERSION@",
-  "fullName": "Firefox OS @NUM_VERSION@ Simulator",
-  "description": "a Firefox OS @NUM_VERSION@ simulator"
-}
deleted file mode 100644
--- a/b2g/simulator/package.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "id": "fxos_simulator@mozilla.org",
-  "name": "fxos_simulator",
-  "version": "1.0.dev",
-  "fullName": "Firefox OS Simulator",
-  "label": "Firefox OS",
-  "description": "a Firefox OS simulator",
-  "author": "Myk Melez (https://github.com/mykmelez)",
-  "contributors": [
-    "Alexandre Poirot (https://github.com/ochameau)",
-    "Anant Narayanan (https://github.com/anantn)",
-    "Brandon Kase (https://github.com/bkase)",
-    "Breck Yunits (https://github.com/breck7)",
-    "César Carruitero (https://github.com/ccarruitero)",
-    "David Gomes (https://github.com/davidgomes)",
-    "Fabrice Desré (https://github.com/fabricedesre)",
-    "Fraser Tweedale (https://github.com/frasertweedale)",
-    "Harald Kirschner (https://github.com/digitarald)",
-    "Jérémie Patonnier (https://github.com/JeremiePat)",
-    "J. Ryan Stinnett (https://github.com/jryans)",
-    "Kan-Ru Chen (陳侃如) (https://github.com/kanru)",
-    "Louis Stowasser (https://github.com/louisstow)",
-    "Luca Greco (https://github.com/rpl)",
-    "Matthew Claypotch (https://github.com/potch)",
-    "Matthew Riley MacPherson (https://github.com/tofumatt)",
-    "Nick Desaulniers (https://github.com/nickdesaulniers)",
-    "Soumen Ganguly (https://github.com/SoumenG)",
-    "Sudheesh Singanamalla (https://github.com/sudheesh001)",
-    "Victor Bjelkholm (https://github.com/VictorBjelkholm)"
-  ],
-  "permissions": {
-    "private-browsing": true
-  },
-  "license": "MPL 2.0",
-  "unpack": true,
-  "dependencies": ["subprocess"]
-}
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/README.md
+++ /dev/null
@@ -1,124 +0,0 @@
-<h2>What's that?</h2>
-Simply package enigmail hard work on providing IPC feature in mozilla platform.
-So we are able to launch child proccesses from javascript,
-and in our case, from addon-sdk libraries :)
-
-<h2>Sample of code:</h2>
-  This object allows to start a process, and read/write data to/from it
-  using stdin/stdout/stderr streams.
-  Usage example:
-
-   const subprocess = require("subprocess");
-   var p = subprocess.call({
-     command:     '/bin/foo',
-     arguments:   ['-v', 'foo'],
-     environment: [ "XYZ=abc", "MYVAR=def" ],
-     charset: 'UTF-8',
-     workdir: '/home/foo',
-     //stdin: "some value to write to stdin\nfoobar",
-     stdin: function(stdin) {
-       stdin.write("some value to write to stdin\nfoobar");
-       stdin.close();
-     },
-     stdout: function(data) {
-       dump("got data on stdout:" + data + "\n");
-     },
-     stderr: function(data) {
-       dump("got data on stderr:" + data + "\n");
-     },
-     done: function(result) {
-       dump("process terminated with " + result.exitCode + "\n");
-     },
-     mergeStderr: false
-   });
-   p.wait(); // wait for the subprocess to terminate
-             // this will block the main thread,
-             // only do if you can wait that long
-
-
-  Description of parameters:
-  --------------------------
-  Apart from <command>, all arguments are optional.
-
-  command:     either a |nsIFile| object pointing to an executable file or a
-              String containing the platform-dependent path to an executable
-              file.
-
-  arguments:   optional string array containing the arguments to the command.
-
-  environment: optional string array containing environment variables to pass
-               to the command. The array elements must have the form
-               "VAR=data". Please note that if environment is defined, it
-               replaces any existing environment variables for the subprocess.
-
-  charset:     Output is decoded with given charset and a string is returned.
-               If charset is undefined, "UTF-8" is used as default.
-               To get binary data, set this to null and the returned string
-               is not decoded in any way.
-
-  workdir:     optional; String containing the platform-dependent path to a
-               directory to become the current working directory of the subprocess.
-
-  stdin:       optional input data for the process to be passed on standard
-               input. stdin can either be a string or a function.
-               A |string| gets written to stdin and stdin gets closed;
-               A |function| gets passed an object with write and close function.
-               Please note that the write() function will return almost immediately;
-               data is always written asynchronously on a separate thread.
-
-  stdout:      an optional function that can receive output data from the
-               process. The stdout-function is called asynchronously; it can be
-               called mutliple times during the execution of a process.
-               At a minimum at each occurance of \n or \r.
-               Please note that null-characters might need to be escaped
-               with something like 'data.replace(/\0/g, "\\0");'.
-
-  stderr:      an optional function that can receive stderr data from the
-               process. The stderr-function is called asynchronously; it can be
-               called mutliple times during the execution of a process. Please
-               note that null-characters might need to be escaped with
-               something like 'data.replace(/\0/g, "\\0");'.
-               (on windows it only gets called once right now)
-
-  done:        optional function that is called when the process has terminated.
-               The exit code from the process available via result.exitCode. If
-               stdout is not defined, then the output from stdout is available
-               via result.stdout. stderr data is in result.stderr
-
-  mergeStderr: optional boolean value. If true, stderr is merged with stdout;
-               no data will be provided to stderr.
-
-
-  Description of object returned by subprocess.call(...)
-  ------------------------------------------------------
-  The object returned by subprocess.call offers a few methods that can be
-  executed:
-
-  wait():         waits for the subprocess to terminate. It is not required to use
-                  wait; done will be called in any case when the subprocess terminated.
-
-  kill(hardKill): kill the subprocess. Any open pipes will be closed and
-                  done will be called.
-                  hardKill [ignored on Windows]:
-                   - false: signal the process terminate (SIGTERM)
-                   - true:  kill the process (SIGKILL)
-
-
-  Other methods in subprocess
-  ---------------------------
-
-  registerDebugHandler(functionRef):   register a handler that is called to get
-                                       debugging information
-  registerLogHandler(functionRef):     register a handler that is called to get error
-                                       messages
-
-  example:
-     subprocess.registerLogHandler( function(s) { dump(s); } );
-
-
-<h2>Credits:</h2>
-All enigmail team working on IPC component.
-  The Initial Developer of this code is Jan Gerber.
-  Portions created by Jan Gerber <j@mailb.org>,
-  Patrick Brunschwig (author of almost all code) <patrick@mozilla-enigmail.org>,
-  Ramalingam Saravanan (from enigmail team) <svn@xmlterm.org>
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/lib/subprocess.js
+++ /dev/null
@@ -1,1543 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-'use strict';
-
-const { Cc, Ci, Cu, ChromeWorker } = require("chrome");
-
-Cu.import("resource://gre/modules/ctypes.jsm");
-
-const NS_LOCAL_FILE = "@mozilla.org/file/local;1";
-
-const Runtime = require("sdk/system/runtime");
-const Environment = require("sdk/system/environment").env;
-const DEFAULT_ENVIRONMENT = [];
-if (Runtime.OS == "Linux" && "DISPLAY" in Environment) {
-  DEFAULT_ENVIRONMENT.push("DISPLAY=" + Environment.DISPLAY);
-}
-
-/*
-Fake require statements to ensure worker scripts are packaged:
-require("subprocess_worker_win.js");
-require("subprocess_worker_unix.js");
-*/
-const URL_PREFIX = module.uri.replace(/subprocess\.js/, "");
-const WORKER_URL_WIN = URL_PREFIX + "subprocess_worker_win.js";
-const WORKER_URL_UNIX = URL_PREFIX + "subprocess_worker_unix.js";
-
-//Windows API definitions
-if (ctypes.size_t.size == 8) {
-    var WinABI = ctypes.default_abi;
-} else {
-    var WinABI = ctypes.winapi_abi;
-}
-const WORD = ctypes.uint16_t;
-const DWORD = ctypes.uint32_t;
-const LPDWORD = DWORD.ptr;
-
-const UINT = ctypes.unsigned_int;
-const BOOL = ctypes.bool;
-const HANDLE = ctypes.size_t;
-const HWND = HANDLE;
-const HMODULE = HANDLE;
-const WPARAM = ctypes.size_t;
-const LPARAM = ctypes.size_t;
-const LRESULT = ctypes.size_t;
-const ULONG_PTR = ctypes.uintptr_t;
-const PVOID = ctypes.voidptr_t;
-const LPVOID = PVOID;
-const LPCTSTR = ctypes.jschar.ptr;
-const LPCWSTR = ctypes.jschar.ptr;
-const LPTSTR = ctypes.jschar.ptr;
-const LPSTR = ctypes.char.ptr;
-const LPCSTR = ctypes.char.ptr;
-const LPBYTE = ctypes.char.ptr;
-
-const CREATE_NEW_CONSOLE = 0x00000010;
-const CREATE_NO_WINDOW = 0x08000000;
-const CREATE_UNICODE_ENVIRONMENT = 0x00000400;
-const STARTF_USESHOWWINDOW = 0x00000001;
-const STARTF_USESTDHANDLES = 0x00000100;
-const SW_HIDE = 0;
-const DUPLICATE_SAME_ACCESS = 0x00000002;
-const STILL_ACTIVE = 259;
-const INFINITE = DWORD(0xFFFFFFFF);
-const WAIT_TIMEOUT = 0x00000102;
-
-/*
-typedef struct _SECURITY_ATTRIBUTES {
- DWORD  nLength;
- LPVOID lpSecurityDescriptor;
- BOOL   bInheritHandle;
-} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
-*/
-const SECURITY_ATTRIBUTES = new ctypes.StructType("SECURITY_ATTRIBUTES", [
-    {"nLength": DWORD},
-    {"lpSecurityDescriptor": LPVOID},
-    {"bInheritHandle": BOOL},
-]);
-
-/*
-typedef struct _STARTUPINFO {
-  DWORD  cb;
-  LPTSTR lpReserved;
-  LPTSTR lpDesktop;
-  LPTSTR lpTitle;
-  DWORD  dwX;
-  DWORD  dwY;
-  DWORD  dwXSize;
-  DWORD  dwYSize;
-  DWORD  dwXCountChars;
-  DWORD  dwYCountChars;
-  DWORD  dwFillAttribute;
-  DWORD  dwFlags;
-  WORD   wShowWindow;
-  WORD   cbReserved2;
-  LPBYTE lpReserved2;
-  HANDLE hStdInput;
-  HANDLE hStdOutput;
-  HANDLE hStdError;
-} STARTUPINFO, *LPSTARTUPINFO;
-*/
-const STARTUPINFO = new ctypes.StructType("STARTUPINFO", [
-    {"cb": DWORD},
-    {"lpReserved": LPTSTR},
-    {"lpDesktop": LPTSTR},
-    {"lpTitle": LPTSTR},
-    {"dwX": DWORD},
-    {"dwY": DWORD},
-    {"dwXSize": DWORD},
-    {"dwYSize": DWORD},
-    {"dwXCountChars": DWORD},
-    {"dwYCountChars": DWORD},
-    {"dwFillAttribute": DWORD},
-    {"dwFlags": DWORD},
-    {"wShowWindow": WORD},
-    {"cbReserved2": WORD},
-    {"lpReserved2": LPBYTE},
-    {"hStdInput": HANDLE},
-    {"hStdOutput": HANDLE},
-    {"hStdError": HANDLE},
-]);
-
-/*
-typedef struct _PROCESS_INFORMATION {
-  HANDLE hProcess;
-  HANDLE hThread;
-  DWORD  dwProcessId;
-  DWORD  dwThreadId;
-} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
-*/
-const PROCESS_INFORMATION = new ctypes.StructType("PROCESS_INFORMATION", [
-    {"hProcess": HANDLE},
-    {"hThread": HANDLE},
-    {"dwProcessId": DWORD},
-    {"dwThreadId": DWORD},
-]);
-
-/*
-typedef struct _OVERLAPPED {
-  ULONG_PTR Internal;
-  ULONG_PTR InternalHigh;
-  union {
-    struct {
-      DWORD Offset;
-      DWORD OffsetHigh;
-    };
-    PVOID  Pointer;
-  };
-  HANDLE    hEvent;
-} OVERLAPPED, *LPOVERLAPPED;
-*/
-const OVERLAPPED = new ctypes.StructType("OVERLAPPED");
-
-//UNIX definitions
-const pid_t = ctypes.int32_t;
-const WNOHANG = 1;
-const F_GETFD = 1;
-const F_SETFL = 4;
-
-const LIBNAME       = 0;
-const O_NONBLOCK    = 1;
-const RLIM_T        = 2;
-const RLIMIT_NOFILE = 3;
-
-function getPlatformValue(valueType) {
-
-    if (! gXulRuntime)
-        gXulRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
-
-    const platformDefaults = {
-        // Windows API:
-        'winnt':   [ 'kernel32.dll' ],
-
-        // Unix API:
-        //            library name   O_NONBLOCK RLIM_T                RLIMIT_NOFILE
-        'darwin':  [ 'libc.dylib',   0x04     , ctypes.uint64_t     , 8 ],
-        'linux':   [ 'libc.so.6',    2024     , ctypes.unsigned_long, 7 ],
-        'freebsd': [ 'libc.so.7',    0x04     , ctypes.int64_t      , 8 ],
-        'openbsd': [ 'libc.so.61.0', 0x04     , ctypes.int64_t      , 8 ],
-        'sunos':   [ 'libc.so',      0x80     , ctypes.unsigned_long, 5 ]
-    }
-
-    return platformDefaults[gXulRuntime.OS.toLowerCase()][valueType];
-}
-
-
-var gDebugFunc = null,
-    gLogFunc = null,
-    gXulRuntime = null;
-
-function LogError(s) {
-    if (gLogFunc)
-        gLogFunc(s);
-    else
-        dump(s);
-}
-
-function debugLog(s) {
-    if (gDebugFunc)
-        gDebugFunc(s);
-}
-
-function setTimeout(callback, timeout) {
-    var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    timer.initWithCallback(callback, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
-};
-
-function getBytes(data) {
-  var string = '';
-  data.forEach(function(x) { string += String.fromCharCode(x < 0 ? x + 256 : x) });
-  return string;
-}
-
-function readString(data, length, charset) {
-    var string = '', bytes = [];
-    for(var i = 0;i < length; i++) {
-        if(data[i] == 0 && charset !== null) // stop on NULL character for non-binary data
-           break
-        bytes.push(data[i]);
-    }
-    if (!bytes || bytes.length == 0)
-        return string;
-    if(charset === null) {
-        return bytes;
-    }
-    return convertBytes(bytes, charset);
-}
-
-function convertBytes(bytes, charset) {
-    var string = '';
-    charset = charset || 'UTF-8';
-    var unicodeConv = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
-                        .getService(Ci.nsIScriptableUnicodeConverter);
-    try {
-        unicodeConv.charset = charset;
-        string = unicodeConv.convertFromByteArray(bytes, bytes.length);
-    } catch (ex) {
-        LogError("String conversion failed: "+ex.toString()+"\n")
-        string = '';
-    }
-    string += unicodeConv.Finish();
-    return string;
-}
-
-
-// temporary solution for removal of nsILocalFile
-function getLocalFileApi() {
-  if ("nsILocalFile" in Ci) {
-    return Ci.nsILocalFile;
-  }
-  else
-    return Ci.nsIFile;
-}
-
-function getCommandStr(command) {
-    let commandStr = null;
-    if (typeof(command) == "string") {
-        let file = Cc[NS_LOCAL_FILE].createInstance(getLocalFileApi());
-        file.initWithPath(command);
-        if (! (file.isExecutable() && file.isFile()))
-            throw("File '"+command+"' is not an executable file");
-        commandStr = command;
-    }
-    else {
-        if (! (command.isExecutable() && command.isFile()))
-            throw("File '"+command.path+"' is not an executable file");
-        commandStr = command.path;
-    }
-
-    return commandStr;
-}
-
-function getWorkDir(workdir) {
-    let workdirStr = null;
-    if (typeof(workdir) == "string") {
-        let file = Cc[NS_LOCAL_FILE].createInstance(getLocalFileApi());
-        file.initWithPath(workdir);
-        if (! (file.isDirectory()))
-            throw("Directory '"+workdir+"' does not exist");
-        workdirStr = workdir;
-    }
-    else if (workdir) {
-        if (! workdir.isDirectory())
-            throw("Directory '"+workdir.path+"' does not exist");
-        workdirStr = workdir.path;
-    }
-    return workdirStr;
-}
-
-
-var subprocess = {
-    call: function(options) {
-        options.mergeStderr = options.mergeStderr || false;
-        options.workdir = options.workdir ||  null;
-        options.environment = options.environment || DEFAULT_ENVIRONMENT;
-        if (options.arguments) {
-            var args = options.arguments;
-            options.arguments = [];
-            args.forEach(function(argument) {
-                options.arguments.push(argument);
-            });
-        } else {
-            options.arguments = [];
-        }
-
-        options.libc = getPlatformValue(LIBNAME);
-
-        if (gXulRuntime.OS.substring(0, 3) == "WIN") {
-            return subprocess_win32(options);
-        } else {
-            return subprocess_unix(options);
-        }
-
-    },
-    registerDebugHandler: function(func) {
-        gDebugFunc = func;
-    },
-    registerLogHandler: function(func) {
-        gLogFunc = func;
-    }
-};
-
-
-
-function subprocess_win32(options) {
-    var kernel32dll = ctypes.open(options.libc),
-        hChildProcess,
-        active = true,
-        done = false,
-        exitCode = -1,
-        child = {},
-        stdinWorker = null,
-        stdoutWorker = null,
-        stderrWorker = null,
-        pendingWriteCount = 0,
-        readers = options.mergeStderr ? 1 : 2,
-        stdinOpenState = 2,
-        error = '',
-        output = '';
-
-    // stdin pipe states
-    const OPEN = 2;
-    const CLOSEABLE = 1;
-    const CLOSED = 0;
-
-    //api declarations
-    /*
-    BOOL WINAPI CloseHandle(
-      __in  HANDLE hObject
-    );
-    */
-    var CloseHandle = kernel32dll.declare("CloseHandle",
-                                            WinABI,
-                                            BOOL,
-                                            HANDLE
-    );
-
-    /*
-    BOOL WINAPI CreateProcess(
-      __in_opt     LPCTSTR lpApplicationName,
-      __inout_opt  LPTSTR lpCommandLine,
-      __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
-      __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
-      __in         BOOL bInheritHandles,
-      __in         DWORD dwCreationFlags,
-      __in_opt     LPVOID lpEnvironment,
-      __in_opt     LPCTSTR lpCurrentDirectory,
-      __in         LPSTARTUPINFO lpStartupInfo,
-      __out        LPPROCESS_INFORMATION lpProcessInformation
-    );
-     */
-    var CreateProcessW = kernel32dll.declare("CreateProcessW",
-                                            WinABI,
-                                            BOOL,
-                                            LPCTSTR,
-                                            LPTSTR,
-                                            SECURITY_ATTRIBUTES.ptr,
-                                            SECURITY_ATTRIBUTES.ptr,
-                                            BOOL,
-                                            DWORD,
-                                            LPVOID,
-                                            LPCTSTR,
-                                            STARTUPINFO.ptr,
-                                            PROCESS_INFORMATION.ptr
-                                         );
-
-//     /*
-//     BOOL WINAPI ReadFile(
-//       __in         HANDLE hFile,
-//       __out        LPVOID ReadFileBuffer,
-//       __in         DWORD nNumberOfBytesToRead,
-//       __out_opt    LPDWORD lpNumberOfBytesRead,
-//       __inout_opt  LPOVERLAPPED lpOverlapped
-//     );
-//     */
-//     var ReadFileBufferSize = 1024,
-//         ReadFileBuffer = ctypes.char.array(ReadFileBufferSize),
-//         ReadFile = kernel32dll.declare("ReadFile",
-//                                         WinABI,
-//                                         BOOL,
-//                                         HANDLE,
-//                                         ReadFileBuffer,
-//                                         DWORD,
-//                                         LPDWORD,
-//                                         OVERLAPPED.ptr
-//     );
-//
-//     /*
-//     BOOL WINAPI PeekNamedPipe(
-//       __in       HANDLE hNamedPipe,
-//       __out_opt  LPVOID lpBuffer,
-//       __in       DWORD nBufferSize,
-//       __out_opt  LPDWORD lpBytesRead,
-//       __out_opt  LPDWORD lpTotalBytesAvail,
-//       __out_opt  LPDWORD lpBytesLeftThisMessage
-//     );
-//     */
-//     var PeekNamedPipe = kernel32dll.declare("PeekNamedPipe",
-//                                         WinABI,
-//                                         BOOL,
-//                                         HANDLE,
-//                                         ReadFileBuffer,
-//                                         DWORD,
-//                                         LPDWORD,
-//                                         LPDWORD,
-//                                         LPDWORD
-//     );
-//
-//     /*
-//     BOOL WINAPI WriteFile(
-//       __in         HANDLE hFile,
-//       __in         LPCVOID lpBuffer,
-//       __in         DWORD nNumberOfBytesToWrite,
-//       __out_opt    LPDWORD lpNumberOfBytesWritten,
-//       __inout_opt  LPOVERLAPPED lpOverlapped
-//     );
-//     */
-//     var WriteFile = kernel32dll.declare("WriteFile",
-//                                         WinABI,
-//                                         BOOL,
-//                                         HANDLE,
-//                                         ctypes.char.ptr,
-//                                         DWORD,
-//                                         LPDWORD,
-//                                         OVERLAPPED.ptr
-//     );
-
-    /*
-    BOOL WINAPI CreatePipe(
-      __out     PHANDLE hReadPipe,
-      __out     PHANDLE hWritePipe,
-      __in_opt  LPSECURITY_ATTRIBUTES lpPipeAttributes,
-      __in      DWORD nSize
-    );
-    */
-    var CreatePipe = kernel32dll.declare("CreatePipe",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE.ptr,
-                                        HANDLE.ptr,
-                                        SECURITY_ATTRIBUTES.ptr,
-                                        DWORD
-    );
-
-    /*
-    HANDLE WINAPI GetCurrentProcess(void);
-    */
-    var GetCurrentProcess = kernel32dll.declare("GetCurrentProcess",
-                                        WinABI,
-                                        HANDLE
-    );
-
-    /*
-    DWORD WINAPI GetLastError(void);
-    */
-    var GetLastError = kernel32dll.declare("GetLastError",
-                                        WinABI,
-                                        DWORD
-    );
-
-    /*
-    BOOL WINAPI DuplicateHandle(
-      __in   HANDLE hSourceProcessHandle,
-      __in   HANDLE hSourceHandle,
-      __in   HANDLE hTargetProcessHandle,
-      __out  LPHANDLE lpTargetHandle,
-      __in   DWORD dwDesiredAccess,
-      __in   BOOL bInheritHandle,
-      __in   DWORD dwOptions
-    );
-    */
-    var DuplicateHandle = kernel32dll.declare("DuplicateHandle",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE,
-                                        HANDLE,
-                                        HANDLE,
-                                        HANDLE.ptr,
-                                        DWORD,
-                                        BOOL,
-                                        DWORD
-    );
-
-
-    /*
-    BOOL WINAPI GetExitCodeProcess(
-      __in   HANDLE hProcess,
-      __out  LPDWORD lpExitCode
-    );
-    */
-    var GetExitCodeProcess = kernel32dll.declare("GetExitCodeProcess",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE,
-                                        LPDWORD
-    );
-
-    /*
-    DWORD WINAPI WaitForSingleObject(
-      __in  HANDLE hHandle,
-      __in  DWORD dwMilliseconds
-    );
-    */
-    var WaitForSingleObject = kernel32dll.declare("WaitForSingleObject",
-                                        WinABI,
-                                        DWORD,
-                                        HANDLE,
-                                        DWORD
-    );
-
-    /*
-    BOOL WINAPI TerminateProcess(
-      __in  HANDLE hProcess,
-      __in  UINT uExitCode
-    );
-    */
-    var TerminateProcess = kernel32dll.declare("TerminateProcess",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE,
-                                        UINT
-    );
-
-    //functions
-    function popen(command, workdir, args, environment, child) {
-        //escape arguments
-        args.unshift(command);
-        for (var i = 0; i < args.length; i++) {
-          if (typeof args[i] != "string") { args[i] = args[i].toString(); }
-          /* quote arguments with spaces */
-          if (args[i].match(/\s/)) {
-            args[i] = "\"" + args[i] + "\"";
-          }
-          /* If backslash is followed by a quote, double it */
-          args[i] = args[i].replace(/\\\"/g, "\\\\\"");
-        }
-        command = args.join(' ');
-
-        environment = environment || [];
-        if(environment.length) {
-            //An environment block consists of
-            //a null-terminated block of null-terminated strings.
-            //Using CREATE_UNICODE_ENVIRONMENT so needs to be jschar
-            environment = ctypes.jschar.array()(environment.join('\0') + '\0');
-        } else {
-            environment = null;
-        }
-
-        var hOutputReadTmp = new HANDLE(),
-            hOutputRead = new HANDLE(),
-            hOutputWrite = new HANDLE();
-
-        var hErrorRead = new HANDLE(),
-            hErrorReadTmp = new HANDLE(),
-            hErrorWrite = new HANDLE();
-
-        var hInputRead = new HANDLE(),
-            hInputWriteTmp = new HANDLE(),
-            hInputWrite = new HANDLE();
-
-        // Set up the security attributes struct.
-        var sa = new SECURITY_ATTRIBUTES();
-        sa.nLength = SECURITY_ATTRIBUTES.size;
-        sa.lpSecurityDescriptor = null;
-        sa.bInheritHandle = true;
-
-        // Create output pipe.
-
-        if(!CreatePipe(hOutputReadTmp.address(), hOutputWrite.address(), sa.address(), 0))
-            LogError('CreatePipe hOutputReadTmp failed');
-
-        if(options.mergeStderr) {
-          // Create a duplicate of the output write handle for the std error
-          // write handle. This is necessary in case the child application
-          // closes one of its std output handles.
-          if (!DuplicateHandle(GetCurrentProcess(), hOutputWrite,
-                               GetCurrentProcess(), hErrorWrite.address(), 0,
-                               true, DUPLICATE_SAME_ACCESS))
-             LogError("DuplicateHandle hOutputWrite failed");
-        } else {
-            // Create error pipe.
-            if(!CreatePipe(hErrorReadTmp.address(), hErrorWrite.address(), sa.address(), 0))
-                LogError('CreatePipe hErrorReadTmp failed');
-        }
-
-        // Create input pipe.
-        if (!CreatePipe(hInputRead.address(),hInputWriteTmp.address(),sa.address(), 0))
-            LogError("CreatePipe hInputRead failed");
-
-        // Create new output/error read handle and the input write handles. Set
-        // the Properties to FALSE. Otherwise, the child inherits the
-        // properties and, as a result, non-closeable handles to the pipes
-        // are created.
-        if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp,
-                             GetCurrentProcess(),
-                             hOutputRead.address(), // Address of new handle.
-                             0, false, // Make it uninheritable.
-                             DUPLICATE_SAME_ACCESS))
-             LogError("DupliateHandle hOutputReadTmp failed");
-
-        if(!options.mergeStderr) {
-            if (!DuplicateHandle(GetCurrentProcess(), hErrorReadTmp,
-                             GetCurrentProcess(),
-                             hErrorRead.address(), // Address of new handle.
-                             0, false, // Make it uninheritable.
-                             DUPLICATE_SAME_ACCESS))
-             LogError("DupliateHandle hErrorReadTmp failed");
-        }
-        if (!DuplicateHandle(GetCurrentProcess(), hInputWriteTmp,
-                             GetCurrentProcess(),
-                             hInputWrite.address(), // Address of new handle.
-                             0, false, // Make it uninheritable.
-                             DUPLICATE_SAME_ACCESS))
-          LogError("DupliateHandle hInputWriteTmp failed");
-
-        // Close inheritable copies of the handles.
-        if (!CloseHandle(hOutputReadTmp)) LogError("CloseHandle hOutputReadTmp failed");
-        if(!options.mergeStderr)
-            if (!CloseHandle(hErrorReadTmp)) LogError("CloseHandle hErrorReadTmp failed");
-        if (!CloseHandle(hInputWriteTmp)) LogError("CloseHandle failed");
-
-        var pi = new PROCESS_INFORMATION();
-        var si = new STARTUPINFO();
-
-        si.cb = STARTUPINFO.size;
-        si.dwFlags = STARTF_USESTDHANDLES;
-        si.hStdInput  = hInputRead;
-        si.hStdOutput = hOutputWrite;
-        si.hStdError  = hErrorWrite;
-
-        // Launch the process
-        if(!CreateProcessW(null,            // executable name
-                           command,         // command buffer
-                           null,            // process security attribute
-                           null,            // thread security attribute
-                           true,            // inherits system handles
-                           CREATE_UNICODE_ENVIRONMENT|CREATE_NO_WINDOW, // process flags
-                           environment,     // envrionment block
-                           workdir,          // set as current directory
-                           si.address(),    // (in) startup information
-                           pi.address()     // (out) process information
-        ))
-            throw("Fatal - Could not launch subprocess '"+command+"'");
-
-        // Close any unnecessary handles.
-        if (!CloseHandle(pi.hThread))
-            LogError("CloseHandle pi.hThread failed");
-
-        // Close pipe handles (do not continue to modify the parent).
-        // You need to make sure that no handles to the write end of the
-        // output pipe are maintained in this process or else the pipe will
-        // not close when the child process exits and the ReadFile will hang.
-        if (!CloseHandle(hInputRead)) LogError("CloseHandle hInputRead failed");
-        if (!CloseHandle(hOutputWrite)) LogError("CloseHandle hOutputWrite failed");
-        if (!CloseHandle(hErrorWrite)) LogError("CloseHandle hErrorWrite failed");
-
-        //return values
-        child.stdin = hInputWrite;
-        child.stdout = hOutputRead;
-        child.stderr = options.mergeStderr ? undefined : hErrorRead;
-        child.process = pi.hProcess;
-        return pi.hProcess;
-    }
-
-    /*
-     * createStdinWriter ()
-     *
-     * Create a ChromeWorker object for writing data to the subprocess' stdin
-     * pipe. The ChromeWorker object lives on a separate thread; this avoids
-     * internal deadlocks.
-     */
-    function createStdinWriter() {
-        debugLog("Creating new stdin worker\n");
-        stdinWorker = new ChromeWorker(WORKER_URL_WIN);
-        stdinWorker.onmessage = function(event) {
-            switch(event.data) {
-            case "WriteOK":
-                pendingWriteCount--;
-                debugLog("got OK from stdinWorker - remaining count: "+pendingWriteCount+"\n");
-                break;
-            case "ClosedOK":
-                stdinOpenState = CLOSED;
-                debugLog("Stdin pipe closed\n");
-                break;
-            default:
-                debugLog("got msg from stdinWorker: "+event.data+"\n");
-            }
-        }
-        stdinWorker.onerror = function(error) {
-            pendingWriteCount--;
-            LogError("got error from stdinWorker: "+error.message+"\n");
-        }
-
-        stdinWorker.postMessage({msg: "init", libc: options.libc});
-    }
-
-    /*
-     * writeStdin()
-     * @data: String containing the data to write
-     *
-     * Write data to the subprocess' stdin (equals to sending a request to the
-     * ChromeWorker object to write the data).
-     */
-    function writeStdin(data) {
-        ++pendingWriteCount;
-        debugLog("sending "+data.length+" bytes to stdinWorker\n");
-        var pipePtr = parseInt(ctypes.cast(child.stdin.address(), ctypes.uintptr_t).value);
-
-        stdinWorker.postMessage({
-                msg: 'write',
-                pipe: pipePtr,
-                data: data
-            });
-    }
-
-    /*
-     * closeStdinHandle()
-     *
-     * Close the stdin pipe, either directly or by requesting the ChromeWorker to
-     * close the pipe. The ChromeWorker will only close the pipe after the last write
-     * request process is done.
-     */
-
-    function closeStdinHandle() {
-        debugLog("trying to close stdin\n");
-        if (stdinOpenState != OPEN) return;
-        stdinOpenState = CLOSEABLE;
-
-        if (stdinWorker) {
-            debugLog("sending close stdin to worker\n");
-            var pipePtr = parseInt(ctypes.cast(child.stdin.address(), ctypes.uintptr_t).value);
-            stdinWorker.postMessage({
-                msg: 'close',
-                pipe: pipePtr
-            });
-        }
-        else {
-            stdinOpenState = CLOSED;
-            debugLog("Closing Stdin\n");
-            CloseHandle(child.stdin) || LogError("CloseHandle hInputWrite failed");
-        }
-    }
-
-
-    /*
-     * createReader(pipe, name)
-     *
-     * @pipe: handle to the pipe
-     * @name: String containing the pipe name (stdout or stderr)
-     *
-     * Create a ChromeWorker object for reading data asynchronously from
-     * the pipe (i.e. on a separate thread), and passing the result back to
-     * the caller.
-     */
-    function createReader(pipe, name, callbackFunc) {
-        var worker = new ChromeWorker(WORKER_URL_WIN);
-        worker.onmessage = function(event) {
-            switch(event.data.msg) {
-            case "data":
-                debugLog("got "+event.data.count+" bytes from "+name+"\n");
-                var data = '';
-                if (options.charset === null) {
-                    data = getBytes(event.data.data);
-                }
-                else {
-                    try {
-                        data = convertBytes(event.data.data, options.charset);
-                    }
-                    catch(ex) {
-                        console.warn("error decoding output: " + ex);
-                        data = getBytes(event.data.data);
-                    }
-                }
-
-                callbackFunc(data);
-                break;
-            case "done":
-                debugLog("Pipe "+name+" closed\n");
-                --readers;
-                if (readers == 0) cleanup();
-                break;
-            default:
-                debugLog("Got msg from "+name+": "+event.data.data+"\n");
-            }
-        }
-
-        worker.onerror = function(errorMsg) {
-            LogError("Got error from "+name+": "+errorMsg.message);
-        }
-
-        var pipePtr = parseInt(ctypes.cast(pipe.address(), ctypes.uintptr_t).value);
-
-        worker.postMessage({
-                msg: 'read',
-                pipe: pipePtr,
-                libc: options.libc,
-                charset: options.charset === null ? "null" : options.charset,
-                name: name
-            });
-
-        return worker;
-    }
-
-    /*
-     * readPipes()
-     *
-     * Open the pipes for reading from stdout and stderr
-     */
-    function readPipes() {
-
-        stdoutWorker = createReader(child.stdout, "stdout", function (data) {
-            if(options.stdout) {
-                setTimeout(function() {
-                    options.stdout(data);
-                }, 0);
-            } else {
-                output += data;
-            }
-        });
-
-
-        if (!options.mergeStderr) stderrWorker = createReader(child.stderr, "stderr", function (data) {
-            if(options.stderr) {
-                setTimeout(function() {
-                    options.stderr(data);
-                }, 0);
-            } else {
-                error += data;
-            }
-        });
-    }
-
-    /*
-     * cleanup()
-     *
-     * close stdin if needed, get the exit code from the subprocess and invoke
-     * the caller's done() function.
-     *
-     * Note: because stdout() and stderr() are called using setTimeout, we need to
-     * do the same here in order to guarantee the message sequence.
-     */
-    function cleanup() {
-        debugLog("Cleanup called\n");
-        if(active) {
-            active = false;
-
-            closeStdinHandle(); // should only be required in case of errors
-
-            var exit = new DWORD();
-            GetExitCodeProcess(child.process, exit.address());
-            exitCode = exit.value;
-
-            if (stdinWorker)
-                stdinWorker.postMessage({msg: 'stop'})
-
-            setTimeout(function _done() {
-                if (options.done) {
-                    try {
-                        options.done({
-                            exitCode: exitCode,
-                            stdout: output,
-                            stderr: error,
-                        });
-                    }
-                    catch (ex) {
-                        // prevent from blocking if options.done() throws an error
-                        done = true;
-                        throw ex;
-                    }
-                }
-                done = true;
-            }, 0);
-            kernel32dll.close();
-        }
-    }
-
-    var cmdStr = getCommandStr(options.command);
-    var workDir = getWorkDir(options.workdir);
-
-    //main
-    hChildProcess = popen(cmdStr, workDir, options.arguments, options.environment, child);
-
-    readPipes();
-
-    if (options.stdin) {
-       createStdinWriter();
-
-        if(typeof(options.stdin) == 'function') {
-            try {
-                options.stdin({
-                    write: function(data) {
-                        writeStdin(data);
-                    },
-                    close: function() {
-                        closeStdinHandle();
-                    }
-                });
-            }
-            catch (ex) {
-                // prevent from failing if options.stdin() throws an exception
-                closeStdinHandle();
-                throw ex;
-            }
-        } else {
-            writeStdin(options.stdin);
-            closeStdinHandle();
-        }
-    }
-    else
-        closeStdinHandle();
-
-    return {
-        kill: function(hardKill) {
-            // hardKill is currently ignored on Windows
-            var r = !!TerminateProcess(child.process, 255);
-            cleanup(-1);
-            return r;
-        },
-        wait: function() {
-            // wait for async operations to complete
-            var thread = Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager).currentThread;
-            while (!done) thread.processNextEvent(true);
-
-            return exitCode;
-        }
-    }
-}
-
-
-function subprocess_unix(options) {
-    // stdin pipe states
-    const OPEN = 2;
-    const CLOSEABLE = 1;
-    const CLOSED = 0;
-
-    var libc = ctypes.open(options.libc),
-        active = true,
-        done = false,
-        exitCode = -1,
-        workerExitCode = 0,
-        child = {},
-        pid = -1,
-        stdinWorker = null,
-        stdoutWorker = null,
-        stderrWorker = null,
-        pendingWriteCount = 0,
-        readers = options.mergeStderr ? 1 : 2,
-        stdinOpenState = OPEN,
-        error = '',
-        output = '';
-
-    //api declarations
-
-    //pid_t fork(void);
-    var fork = libc.declare("fork",
-                         ctypes.default_abi,
-                         pid_t
-    );
-
-    //NULL terminated array of strings, argv[0] will be command >> + 2
-    var argv = ctypes.char.ptr.array(options.arguments.length + 2);
-    var envp = ctypes.char.ptr.array(options.environment.length + 1);
-
-    // posix_spawn_file_actions_t is a complex struct that may be different on
-    // each platform. We do not care about its attributes, we don't need to
-    // get access to them, but we do need to allocate the right amount
-    // of memory for it.
-    // Bug 936297 - Use OS.File internals to fetch
-    // sizeof(posix_spawn_file_actions_t)
-    var { OS } = Cu.import("resource://gre/modules/osfile.jsm", {});
-    var sizeof_file_actions_t = OS.Constants.libc.OSFILE_SIZEOF_DIRENT;
-    var posix_spawn_file_actions_t = ctypes.uint8_t.array(sizeof_file_actions_t);
-
-    //int posix_spawn(pid_t *restrict pid, const char *restrict path,
-    //   const posix_spawn_file_actions_t *file_actions,
-    //   const posix_spawnattr_t *restrict attrp,
-    //   char *const argv[restrict], char *const envp[restrict]);
-    var posix_spawn = libc.declare("posix_spawn",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         pid_t.ptr,
-                         ctypes.char.ptr,
-                         posix_spawn_file_actions_t.ptr,
-                         ctypes.voidptr_t,
-                         argv,
-                         envp
-    );
-
-    //int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions);
-    var posix_spawn_file_actions_init = libc.declare("posix_spawn_file_actions_init",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         posix_spawn_file_actions_t.ptr
-    );
-
-    //int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions);
-    var posix_spawn_file_actions_destroy = libc.declare("posix_spawn_file_actions_destroy",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         posix_spawn_file_actions_t.ptr
-    );
-
-    // int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *
-    //                                      file_actions, int fildes, int newfildes);
-    var posix_spawn_file_actions_adddup2 = libc.declare("posix_spawn_file_actions_adddup2",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         posix_spawn_file_actions_t.ptr,
-                         ctypes.int,
-                         ctypes.int
-    );
-
-    // int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *
-    //                                       file_actions, int fildes);
-    var posix_spawn_file_actions_addclose = libc.declare("posix_spawn_file_actions_addclose",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         posix_spawn_file_actions_t.ptr,
-                         ctypes.int
-    );
-
-    //int pipe(int pipefd[2]);
-    var pipefd = ctypes.int.array(2);
-    var pipe = libc.declare("pipe",
-                         ctypes.default_abi,
-                         ctypes.int,
-                         pipefd
-    );
-
-    //int close(int fd);
-    var close = libc.declare("close",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          ctypes.int
-    );
-
-    //pid_t waitpid(pid_t pid, int *status, int options);
-    var waitpid = libc.declare("waitpid",
-                          ctypes.default_abi,
-                          pid_t,
-                          pid_t,
-                          ctypes.int.ptr,
-                          ctypes.int
-    );
-
-    //int kill(pid_t pid, int sig);
-    var kill = libc.declare("kill",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          pid_t,
-                          ctypes.int
-    );
-
-    //int read(int fd, void *buf, size_t count);
-    var bufferSize = 1024;
-    var buffer = ctypes.char.array(bufferSize);
-    var read = libc.declare("read",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          ctypes.int,
-                          buffer,
-                          ctypes.int
-    );
-
-    //ssize_t write(int fd, const void *buf, size_t count);
-    var write = libc.declare("write",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          ctypes.int,
-                          ctypes.char.ptr,
-                          ctypes.int
-    );
-
-    //int chdir(const char *path);
-    var chdir = libc.declare("chdir",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          ctypes.char.ptr
-    );
-
-    //int fcntl(int fd, int cmd, ... /* arg */ );
-    var fcntl = libc.declare("fcntl",
-                          ctypes.default_abi,
-                          ctypes.int,
-                          ctypes.int,
-                          ctypes.int,
-                          ctypes.int
-    );
-
-    function popen(command, workdir, args, environment, child) {
-        var _in,
-            _out,
-            _err,
-            pid,
-            rc;
-        _in = new pipefd();
-        _out = new pipefd();
-        if(!options.mergeStderr)
-            _err = new pipefd();
-
-        var _args = argv();
-        args.unshift(command);
-        for(var i=0;i<args.length;i++) {
-            _args[i] = ctypes.char.array()(args[i]);
-        }
-        var _envp = envp();
-        for(var i=0;i<environment.length;i++) {
-            _envp[i] = ctypes.char.array()(environment[i]);
-            // LogError(_envp);
-        }
-
-        rc = pipe(_in);
-        if (rc < 0) {
-            return -1;
-        }
-        rc = pipe(_out);
-        fcntl(_out[0], F_SETFL, getPlatformValue(O_NONBLOCK));
-        if (rc < 0) {
-            close(_in[0]);
-            close(_in[1]);
-            return -1
-        }
-        if(!options.mergeStderr) {
-            rc = pipe(_err);
-            fcntl(_err[0], F_SETFL, getPlatformValue(O_NONBLOCK));
-            if (rc < 0) {
-                close(_in[0]);
-                close(_in[1]);
-                close(_out[0]);
-                close(_out[1]);
-                return -1
-            }
-        }
-
-        let STDIN_FILENO = 0;
-        let STDOUT_FILENO = 1;
-        let STDERR_FILENO = 2;
-
-        let action = posix_spawn_file_actions_t();
-        posix_spawn_file_actions_init(action.address());
-
-        posix_spawn_file_actions_adddup2(action.address(), _in[0], STDIN_FILENO);
-        posix_spawn_file_actions_addclose(action.address(), _in[1]);
-        posix_spawn_file_actions_addclose(action.address(), _in[0]);
-
-        posix_spawn_file_actions_adddup2(action.address(), _out[1], STDOUT_FILENO);
-        posix_spawn_file_actions_addclose(action.address(), _out[1]);
-        posix_spawn_file_actions_addclose(action.address(), _out[0]);
-
-        if (!options.mergeStderr) {
-          posix_spawn_file_actions_adddup2(action.address(), _err[1], STDERR_FILENO);
-          posix_spawn_file_actions_addclose(action.address(), _err[1]);
-          posix_spawn_file_actions_addclose(action.address(), _err[0]);
-        }
-
-        // posix_spawn doesn't support setting a custom workdir for the child,
-        // so change the cwd in the parent process before launching the child process.
-        if (workdir) {
-          if (chdir(workdir) < 0) {
-            throw new Error("Unable to change workdir before launching child process");
-          }
-        }
-
-        closeOtherFds(action, _in[1], _out[0], options.mergeStderr ? undefined : _err[0]);
-
-        let id = pid_t(0);
-        let rv = posix_spawn(id.address(), command, action.address(), null, _args, _envp);
-        posix_spawn_file_actions_destroy(action.address());
-        if (rv != 0) {
-          // we should not really end up here
-          if(!options.mergeStderr) {
-            close(_err[0]);
-            close(_err[1]);
-          }
-          close(_out[0]);
-          close(_out[1]);
-          close(_in[0]);
-          close(_in[1]);
-          throw new Error("Fatal - failed to create subprocess '"+command+"'");
-        }
-        pid = id.value;
-
-        close(_in[0]);
-        close(_out[1]);
-        if (!options.mergeStderr)
-          close(_err[1]);
-        child.stdin  = _in[1];
-        child.stdout = _out[0];
-        child.stderr = options.mergeStderr ? undefined : _err[0];
-        child.pid = pid;
-
-        return pid;
-    }
-
-
-    // close any file descriptors that are not required for the process
-    function closeOtherFds(action, fdIn, fdOut, fdErr) {
-        // Unfortunately on mac, any fd registered in posix_spawn_file_actions_addclose
-        // that can't be closed correctly will make posix_spawn fail...
-        // Even if we ensure registering only still opened fds.
-        if (gXulRuntime.OS == "Darwin")
-            return;
-
-        var maxFD = 256; // arbitrary max
-
-
-        var rlim_t = getPlatformValue(RLIM_T);
-
-        const RLIMITS = new ctypes.StructType("RLIMITS", [
-            {"rlim_cur": rlim_t},
-            {"rlim_max": rlim_t}
-        ]);
-
-        try {
-            var getrlimit = libc.declare("getrlimit",
-                                  ctypes.default_abi,
-                                  ctypes.int,
-                                  ctypes.int,
-                                  RLIMITS.ptr
-            );
-
-            var rl = new RLIMITS();
-            if (getrlimit(getPlatformValue(RLIMIT_NOFILE), rl.address()) == 0) {
-                maxFD = rl.rlim_cur;
-            }
-            debugLog("getlimit: maxFD="+maxFD+"\n");
-
-        }
-        catch(ex) {
-            debugLog("getrlimit: no such function on this OS\n");
-            debugLog(ex.toString());
-        }
-
-        // close any file descriptors
-        // fd's 0-2 are already closed
-        for (var i = 3; i < maxFD; i++) {
-            if (i != fdIn && i != fdOut && i != fdErr && fcntl(i, F_GETFD, -1) >= 0) {
-                posix_spawn_file_actions_addclose(action.address(), i);
-            }
-        }
-    }
-
-    /*
-     * createStdinWriter ()
-     *
-     * Create a ChromeWorker object for writing data to the subprocess' stdin
-     * pipe. The ChromeWorker object lives on a separate thread; this avoids
-     * internal deadlocks.
-     */
-    function createStdinWriter() {
-        debugLog("Creating new stdin worker\n");
-        stdinWorker = new ChromeWorker(WORKER_URL_UNIX);
-        stdinWorker.onmessage = function(event) {
-            switch (event.data.msg) {
-            case "info":
-                switch(event.data.data) {
-                case "WriteOK":
-                    pendingWriteCount--;
-                    debugLog("got OK from stdinWorker - remaining count: "+pendingWriteCount+"\n");
-                    break;
-                case "ClosedOK":
-                    stdinOpenState = CLOSED;
-                    debugLog("Stdin pipe closed\n");
-                    break;
-                default:
-                    debugLog("got msg from stdinWorker: "+event.data.data+"\n");
-                }
-                break;
-            case "debug":
-                debugLog("stdinWorker: "+event.data.data+"\n");
-                break;
-            case "error":
-                LogError("got error from stdinWorker: "+event.data.data+"\n");
-                pendingWriteCount = 0;
-                stdinOpenState = CLOSED;
-            }
-        }
-        stdinWorker.onerror = function(error) {
-            pendingWriteCount = 0;
-            closeStdinHandle();
-            LogError("got error from stdinWorker: "+error.message+"\n");
-        }
-        stdinWorker.postMessage({msg: "init", libc: options.libc});
-    }
-
-    /*
-     * writeStdin()
-     * @data: String containing the data to write
-     *
-     * Write data to the subprocess' stdin (equals to sending a request to the
-     * ChromeWorker object to write the data).
-     */
-    function writeStdin(data) {
-        if (stdinOpenState == CLOSED) return; // do not write to closed pipes
-
-        ++pendingWriteCount;
-        debugLog("sending "+data.length+" bytes to stdinWorker\n");
-        var pipe = parseInt(child.stdin);
-
-        stdinWorker.postMessage({
-            msg: 'write',
-            pipe: pipe,
-            data: data
-        });
-    }
-
-
-    /*
-     * closeStdinHandle()
-     *
-     * Close the stdin pipe, either directly or by requesting the ChromeWorker to
-     * close the pipe. The ChromeWorker will only close the pipe after the last write
-     * request process is done.
-     */
-
-    function closeStdinHandle() {
-        debugLog("trying to close stdin\n");
-        if (stdinOpenState != OPEN) return;
-        stdinOpenState = CLOSEABLE;
-
-        if (stdinWorker) {
-            debugLog("sending close stdin to worker\n");
-            var pipePtr = parseInt(child.stdin);
-
-            stdinWorker.postMessage({
-                msg: 'close',
-                pipe: pipePtr
-            });
-        }
-        else {
-            stdinOpenState = CLOSED;
-            debugLog("Closing Stdin\n");
-            close(child.stdin) && LogError("CloseHandle stdin failed");
-        }
-    }
-
-
-    /*
-     * createReader(pipe, name)
-     *
-     * @pipe: handle to the pipe
-     * @name: String containing the pipe name (stdout or stderr)
-     * @callbackFunc: function to be called with the read data
-     *
-     * Create a ChromeWorker object for reading data asynchronously from
-     * the pipe (i.e. on a separate thread), and passing the result back to
-     * the caller.
-     *
-     */
-    function createReader(pipe, name, callbackFunc) {
-        var worker = new ChromeWorker(WORKER_URL_UNIX);
-        worker.onmessage = function(event) {
-            switch(event.data.msg) {
-            case "data":
-                debugLog("got "+event.data.count+" bytes from "+name+"\n");
-                var data = '';
-                if (options.charset === null) {
-                    data = getBytes(event.data.data);
-                }
-                else {
-                    try {
-                        data = convertBytes(event.data.data, options.charset);
-                    }
-                    catch(ex) {
-                        console.warn("error decoding output: " + ex);
-                        data = getBytes(event.data.data);
-                    }
-                }
-
-                callbackFunc(data);
-                break;
-            case "done":
-                debugLog("Pipe "+name+" closed\n");
-                if (event.data.data != 0) workerExitCode = event.data.data;
-                --readers;
-                if (readers == 0) cleanup();
-                break;
-            default:
-                debugLog("Got msg from "+name+": "+event.data.data+"\n");
-            }
-        }
-        worker.onerror = function(error) {
-            LogError("Got error from "+name+": "+error.message);
-        }
-
-        worker.postMessage({
-                msg: 'read',
-                pipe: pipe,
-                pid: pid,
-                libc: options.libc,
-                charset: options.charset === null ? "null" : options.charset,
-                name: name
-            });
-
-        return worker;
-    }
-
-    /*
-     * readPipes()
-     *
-     * Open the pipes for reading from stdout and stderr
-     */
-    function readPipes() {
-
-        stdoutWorker = createReader(child.stdout, "stdout", function (data) {
-            if(options.stdout) {
-                setTimeout(function() {
-                    options.stdout(data);
-                }, 0);
-            } else {
-                output += data;
-            }
-        });
-
-        if (!options.mergeStderr) stderrWorker = createReader(child.stderr, "stderr", function (data) {
-            if(options.stderr) {
-                setTimeout(function() {
-                    options.stderr(data);
-                 }, 0);
-            } else {
-                error += data;
-            }
-        });
-    }
-
-    function cleanup() {
-        debugLog("Cleanup called\n");
-        if(active) {
-            active = false;
-
-            closeStdinHandle(); // should only be required in case of errors
-
-            var result, status = ctypes.int();
-            result = waitpid(child.pid, status.address(), 0);
-            if (result > 0)
-                exitCode = status.value
-            else
-                if (workerExitCode >= 0)
-                    exitCode = workerExitCode
-                else
-                    exitCode = status.value;
-
-            if (stdinWorker)
-                stdinWorker.postMessage({msg: 'stop'})
-
-            setTimeout(function _done() {
-                if (options.done) {
-                    try {
-                        options.done({
-                            exitCode: exitCode,
-                            stdout: output,
-                            stderr: error,
-                        });
-                    }
-                    catch(ex) {
-                        // prevent from blocking if options.done() throws an error
-                        done = true;
-                        throw ex;
-                    }
-
-                }
-                done = true;
-            }, 0);
-
-            libc.close();
-        }
-    }
-
-    //main
-
-    var cmdStr = getCommandStr(options.command);
-    var workDir = getWorkDir(options.workdir);
-
-    child = {};
-    pid = popen(cmdStr, workDir, options.arguments, options.environment, child);
-
-    debugLog("subprocess started; got PID "+pid+"\n");
-
-    readPipes();
-
-    if (options.stdin) {
-        createStdinWriter();
-        if(typeof(options.stdin) == 'function') {
-            try {
-                options.stdin({
-                    write: function(data) {
-                        writeStdin(data);
-                    },
-                    close: function() {
-                        closeStdinHandle();
-                    }
-                });
-            }
-            catch(ex) {
-                // prevent from failing if options.stdin() throws an exception
-                closeStdinHandle();
-                throw ex;
-            }
-        } else {
-            writeStdin(options.stdin);
-            closeStdinHandle();
-        }
-    }
-
-    return {
-        wait: function() {
-            // wait for async operations to complete
-            var thread = Cc['@mozilla.org/thread-manager;1'].getService(Ci.nsIThreadManager).currentThread;
-            while (! done) thread.processNextEvent(true)
-            return exitCode;
-        },
-        kill: function(hardKill) {
-            var rv = kill(pid, (hardKill ? 9: 15));
-            cleanup(-1);
-            return rv;
-        }
-    }
-}
-
-
-module.exports = subprocess;
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/lib/subprocess_worker_unix.js
+++ /dev/null
@@ -1,248 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-/*
- * ChromeWorker Object subprocess.jsm on Unix-like systems (Linux, Mac OS X, ...)
- * to process stdin/stdout/stderr on separate threads.
- *
- */
-
-// Being a ChromeWorker object, implicitly uses the following:
-// Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-'use strict';
-
-const BufferSize = 1024;
-
-var libc = null;
-var libcFunc = {};
-
-
-/*
-    struct pollfd {
-         int    fd;       // file descriptor
-         short  events;   // events to look for
-         short  revents;  // events returned
-     };
-*/
-
-var pollfd = new ctypes.StructType("pollfd",
-                        [   {'fd': ctypes.int},
-                            {'events': ctypes.short},
-                            {'revents': ctypes.short}
-                        ]);
-
-var WriteBuffer = ctypes.uint8_t.array(BufferSize);
-var ReadBuffer = ctypes.char.array(BufferSize);
-
-
-const POLLIN     = 0x0001;
-const POLLOUT    = 0x0004;
-
-const POLLERR    = 0x0008;         // some poll error occurred
-const POLLHUP    = 0x0010;         // file descriptor was "hung up"
-const POLLNVAL   = 0x0020;         // requested events "invalid"
-
-const WNOHANG    = 0x01;
-
-const pid_t = ctypes.int32_t;
-
-const INDEFINITE = -1;
-const NOWAIT     = 0;
-const WAITTIME   = 200  // wait time for poll() in ms
-
-function initLibc(libName) {
-    postMessage({msg: "debug", data: "initialising library with "+ libName});
-
-    libc = ctypes.open(libName);
-
-    libcFunc.pollFds = pollfd.array(1);
-
-    // int poll(struct pollfd fds[], nfds_t nfds, int timeout);
-    libcFunc.poll = libc.declare("poll",
-                                  ctypes.default_abi,
-                                  ctypes.int,
-                                  libcFunc.pollFds,
-                                  ctypes.unsigned_int,
-                                  ctypes.int);
-
-    //ssize_t write(int fd, const void *buf, size_t count);
-    // NOTE: buf is declared as array of unsigned int8 instead of char to avoid
-    // implicit charset conversion
-    libcFunc.write = libc.declare("write",
-                                  ctypes.default_abi,
-                                  ctypes.int,
-                                  ctypes.int,
-                                  WriteBuffer,
-                                  ctypes.int);
-
-    //int read(int fd, void *buf, size_t count);
-    libcFunc.read = libc.declare("read",
-                                  ctypes.default_abi,
-                                  ctypes.int,
-                                  ctypes.int,
-                                  ReadBuffer,
-                                  ctypes.int);
-
-    //int pipe(int pipefd[2]);
-    libcFunc.pipefd = ctypes.int.array(2);
-
-    //int close(int fd);
-    libcFunc.close = libc.declare("close",
-                                  ctypes.default_abi,
-                                  ctypes.int,
-                                  ctypes.int);
-
-    //pid_t waitpid(pid_t pid, int *status, int options);
-    libcFunc.waitpid = libc.declare("waitpid",
-                                  ctypes.default_abi,
-                                  pid_t,
-                                  pid_t,
-                                  ctypes.int.ptr,
-                                  ctypes.int);
-}
-
-function closePipe(pipe) {
-    libcFunc.close(pipe);
-}
-
-function writePipe(pipe, data) {
-
-    postMessage({msg: "debug", data: "trying to write to "+pipe});
-
-    let numChunks = Math.floor(data.length / BufferSize);
-    let pData = new WriteBuffer();
-
-    for (var chunk = 0; chunk <= numChunks; chunk ++) {
-        let numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize;
-        for (var i=0; i < numBytes; i++) {
-            pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256;
-        }
-
-        let bytesWritten = libcFunc.write(pipe, pData, numBytes);
-        if (bytesWritten != numBytes) {
-            closePipe();
-            libc.close();
-            postMessage({ msg: "error", data: "error: wrote "+bytesWritten+" instead of "+numBytes+" bytes"});
-            close();
-        }
-    }
-    postMessage({msg: "info", data: "wrote "+data.length+" bytes of data"});
-}
-
-
-function readString(data, length, charset) {
-    var string = '', bytes = [];
-    for(var i = 0;i < length; i++) {
-        if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data
-           break;
-
-        bytes.push(data[i]);
-    }
-
-    return bytes;
-}
-
-function readPipe(pipe, charset, pid) {
-    var p = new libcFunc.pollFds;
-    p[0].fd = pipe;
-    p[0].events = POLLIN | POLLERR | POLLHUP;
-    p[0].revents = 0;
-    var pollTimeout = WAITTIME;
-    var exitCode = -1;
-    var readCount = 0;
-    var result, status = ctypes.int();
-    result = 0;
-
-
-    const i=0;
-    while (true) {
-        if (result == 0) {
-            result = libcFunc.waitpid(pid, status.address(), WNOHANG);
-            if (result > 0) {
-                pollTimeout = NOWAIT;
-                exitCode = parseInt(status.value);
-                postMessage({msg: "debug", data: "waitpid signaled subprocess stop, exitcode="+status.value });
-            }
-        }
-        var r = libcFunc.poll(p, 1, pollTimeout);
-        if (r > 0) {
-            if (p[i].revents & POLLIN) {
-                postMessage({msg: "debug", data: "reading next chunk"});
-                readCount = readPolledFd(p[i].fd, charset);
-                if (readCount == 0) break;
-            }
-
-            if (p[i].revents & POLLHUP) {
-                postMessage({msg: "debug", data: "poll returned HUP"});
-                break;
-            }
-            else if (p[i].revents & POLLERR) {
-                postMessage({msg: "error", data: "poll returned error"});
-                break;
-            }
-            else if (p[i].revents != POLLIN) {
-                postMessage({msg: "error", data: "poll returned "+p[i]});
-                break;
-            }
-        }
-        else
-            if (pollTimeout == 0 || r < 0) break;
-    }
-
-    // continue reading until the buffer is empty
-    while (readCount > 0) {
-      readCount = readPolledFd(pipe, charset);
-    }
-
-    libcFunc.close(pipe);
-    postMessage({msg: "done", data: exitCode });
-    libc.close();
-    close();
-}
-
-function readPolledFd(pipe, charset) {
-    var line = new ReadBuffer();
-    var r = libcFunc.read(pipe, line, BufferSize);
-
-    if (r > 0) {
-        var c = readString(line, r, charset);
-        postMessage({msg: "data", data: c, count: c.length});
-    }
-    return r;
-}
-
-onmessage = function (event) {
-    switch (event.data.msg) {
-    case "init":
-        initLibc(event.data.libc);
-        break;
-    case "read":
-        initLibc(event.data.libc);
-        readPipe(event.data.pipe, event.data.charset, event.data.pid);
-        break;
-    case "write":
-        // data contents:
-        //   msg: 'write'
-        //   data: the data (string) to write
-        //   pipe: ptr to pipe
-        writePipe(event.data.pipe, event.data.data);
-        postMessage({msg: "info", data: "WriteOK"});
-        break;
-    case "close":
-        postMessage({msg: "debug", data: "closing stdin\n"});
-
-        closePipe(event.data.pipe);
-        postMessage({msg: "info", data: "ClosedOK"});
-        break;
-    case "stop":
-        libc.close(); // do not use libc after this point
-        close();
-        break;
-    default:
-        throw("error: Unknown command"+event.data.msg+"\n");
-    }
-    return;
-};
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/lib/subprocess_worker_win.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-/*
- * ChromeWorker Object subprocess.jsm on Windows to process stdin/stdout/stderr
- * on separate threads.
- *
- */
-
-// Being a ChromeWorker object, implicitly uses the following:
-// Components.utils.import("resource://gre/modules/ctypes.jsm");
-
-'use strict';
-
-const BufferSize = 1024;
-
-const BOOL = ctypes.bool;
-const HANDLE = ctypes.size_t;
-const DWORD = ctypes.uint32_t;
-const LPDWORD = DWORD.ptr;
-const PVOID = ctypes.voidptr_t;
-const LPVOID = PVOID;
-
-/*
-typedef struct _OVERLAPPED {
-  ULONG_PTR Internal;
-  ULONG_PTR InternalHigh;
-  union {
-    struct {
-      DWORD Offset;
-      DWORD OffsetHigh;
-    };
-    PVOID  Pointer;
-  };
-  HANDLE    hEvent;
-} OVERLAPPED, *LPOVERLAPPED;
-*/
-const OVERLAPPED = new ctypes.StructType("OVERLAPPED");
-
-var ReadFileBuffer = ctypes.char.array(BufferSize);
-var WriteFileBuffer = ctypes.uint8_t.array(BufferSize);
-
-var kernel32dll = null;
-var libFunc = {};
-
-function initLib(libName) {
-    if (ctypes.size_t.size == 8) {
-        var WinABI = ctypes.default_abi;
-    } else {
-        var WinABI = ctypes.winapi_abi;
-    }
-
-    kernel32dll = ctypes.open(libName);
-
-    /*
-    BOOL WINAPI WriteFile(
-      __in         HANDLE hFile,
-      __in         LPCVOID lpBuffer,
-      __in         DWORD nNumberOfBytesToWrite,
-      __out_opt    LPDWORD lpNumberOfBytesWritten,
-      __inout_opt  LPOVERLAPPED lpOverlapped
-    );
-
-    NOTE: lpBuffer is declared as array of unsigned int8 instead of char to avoid
-           implicit charset conversion
-    */
-    libFunc.WriteFile = kernel32dll.declare("WriteFile",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE,
-                                        WriteFileBuffer,
-                                        DWORD,
-                                        LPDWORD,
-                                        OVERLAPPED.ptr
-    );
-
-    /*
-    BOOL WINAPI ReadFile(
-      __in         HANDLE hFile,
-      __out        LPVOID ReadFileBuffer,
-      __in         DWORD nNumberOfBytesToRead,
-      __out_opt    LPDWORD lpNumberOfBytesRead,
-      __inout_opt  LPOVERLAPPED lpOverlapped
-    );
-    */
-    libFunc.ReadFile = kernel32dll.declare("ReadFile",
-                                        WinABI,
-                                        BOOL,
-                                        HANDLE,
-                                        ReadFileBuffer,
-                                        DWORD,
-                                        LPDWORD,
-                                        OVERLAPPED.ptr
-    );
-
-    /*
-    BOOL WINAPI CloseHandle(
-      __in  HANDLE hObject
-    );
-    */
-    libFunc.CloseHandle = kernel32dll.declare("CloseHandle",
-                                            WinABI,
-                                            BOOL,
-                                            HANDLE
-    );
-}
-
-
-function writePipe(pipe, data) {
-    var bytesWritten = DWORD(0);
-
-    var pData = new WriteFileBuffer();
-
-    var numChunks = Math.floor(data.length / BufferSize);
-    for (var chunk = 0; chunk <= numChunks; chunk ++) {
-        var numBytes = chunk < numChunks ? BufferSize : data.length - chunk * BufferSize;
-        for (var i=0; i < numBytes; i++) {
-            pData[i] = data.charCodeAt(chunk * BufferSize + i) % 256;
-        }
-
-      var r = libFunc.WriteFile(pipe, pData, numBytes, bytesWritten.address(), null);
-      if (bytesWritten.value != numBytes)
-          throw("error: wrote "+bytesWritten.value+" instead of "+numBytes+" bytes");
-    }
-    postMessage("wrote "+data.length+" bytes of data");
-}
-
-function readString(data, length, charset) {
-    var string = '', bytes = [];
-    for(var i = 0;i < length; i++) {
-        if(data[i] == 0 && charset != "null") // stop on NULL character for non-binary data
-           break;
-
-        bytes.push(data[i]);
-    }
-
-    return bytes;
-}
-
-function readPipe(pipe, charset) {
-    while (true) {
-        var bytesRead = DWORD(0);
-        var line = new ReadFileBuffer();
-        var r = libFunc.ReadFile(pipe, line, BufferSize, bytesRead.address(), null);
-
-        if (!r) {
-            // stop if we get an error (such as EOF reached)
-            postMessage({msg: "info", data: "ReadFile failed"});
-            break;
-        }
-
-        if (bytesRead.value > 0) {
-            var c = readString(line, bytesRead.value, charset);
-            postMessage({msg: "data", data: c, count: c.length});
-        }
-        else {
-            break;
-        }
-    }
-    libFunc.CloseHandle(pipe);
-    postMessage({msg: "done"});
-    kernel32dll.close();
-    close();
-}
-
-onmessage = function (event) {
-    let pipePtr;
-    switch (event.data.msg) {
-    case "init":
-        initLib(event.data.libc);
-        break;
-    case "write":
-        // data contents:
-        //   msg: 'write'
-        //   data: the data (string) to write
-        //   pipe: ptr to pipe
-        pipePtr = HANDLE.ptr(event.data.pipe);
-        writePipe(pipePtr.contents, event.data.data);
-        postMessage("WriteOK");
-        break;
-    case "read":
-        initLib(event.data.libc);
-        pipePtr = HANDLE.ptr(event.data.pipe);
-        readPipe(pipePtr.contents, event.data.charset);
-        break;
-    case "close":
-        pipePtr = HANDLE.ptr(event.data.pipe);
-        postMessage("closing stdin\n");
-
-        if (libFunc.CloseHandle(pipePtr.contents)) {
-            postMessage("ClosedOK");
-        }
-        else
-            postMessage("Could not close stdin handle");
-        break;
-    case "stop":
-        kernel32dll.close();
-        close();
-        break;
-    default:
-        throw("error: Unknown command"+event.data.msg+"\n");
-    }
-    return;
-};
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "name": "subprocess",
-    "license": "MPL 1.1/GPL 2.0/LGPL 2.1",
-    "author": "Alexandre Poirot",
-    "contributors": [
-      "Jan Gerber (original creator) <j@mailb.org>",
-      "Patrick Brunschwig (author of almost all code) <patrick@mozilla-enigmail.org>",
-      "Ramalingam Saravanan (from enigmail team) <svn@xmlterm.org>"
-    ],
-    "version": "0.1.1",
-    "dependencies": [
-      "api-utils"
-    ],
-    "description": "Addon-sdk package for subprocess xpcom components from enigmail. Allow to run process, manipulate stdin/out and kill it."
-}
deleted file mode 100644
--- a/b2g/simulator/packages/subprocess/tests/test-subprocess.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-const { Cc, Ci } = require("chrome");
-const subprocess = require("subprocess");
-const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
-
-// For now, only test on windows
-if (env.get('OS') && env.get('OS').match(/Windows/)) {
-
-exports.testWindows = function (test) {
-  test.waitUntilDone();
-  let envTestValue = "OK";
-  let gotStdout = false;
-
-  var p = subprocess.call({
-    // Retrieve windows cmd.exe path from env
-    command:     env.get('ComSpec'),
-    // In order to execute a simple "echo" function
-    arguments:   ['/C', 'echo %ENV_TEST%'], // ' & type CON' should display stdin, but doesn't work
-    // Printing an environnement variable set here by the parent process
-    environment: ['ENV_TEST='+envTestValue],
-
-    stdin: function(stdin) {
-      // Win32 command line is not really made for stdin
-      // So it doesn't seems to work as it's hard to retrieve stdin
-      stdin.write("stdin");
-      stdin.close();
-    },
-    stdout: function(data) {
-      test.assert(!gotStdout,"don't get stdout twice");
-      test.assertEqual(data,envTestValue+"\r\n","stdout contains the environment variable");
-      gotStdout = true;
-    },
-    stderr: function(data) {
-      test.fail("shouldn't get stderr");
-    },
-    done: function() {
-      test.assert(gotStdout, "got stdout before finished");
-      test.done();
-    },
-    mergeStderr: false
-  });
-
-}
-
-exports.testWindowsStderr = function (test) {
-  test.waitUntilDone();
-  let gotStderr = false;
-
-  var p = subprocess.call({
-    command:     env.get('ComSpec'),
-    arguments:   ['/C', 'nonexistent'],
-
-    stdout: function(data) {
-      test.fail("shouldn't get stdout");
-    },
-    stderr: function(data) {
-      test.assert(!gotStderr,"don't get stderr twice");
-      test.assertEqual(
-        data,
-        "'nonexistent' is not recognized as an internal or external command,\r\n" +
-        "operable program or batch file.\r\n",
-        "stderr contains the error message"
-      );
-      gotStderr = true;
-    },
-    done: function() {
-      test.assert(gotStderr, "got stderr before finished");
-      test.done();
-    },
-    mergeStderr: false
-  });
-
-}
-
-}
-
-if (env.get('USER') && env.get('SHELL')) {
-
-exports.testUnix = function (test) {
-  test.waitUntilDone();
-  let envTestValue = "OK";
-  let gotStdout = false;
-
-  var p = subprocess.call({
-    command:     '/bin/sh',
-    // Print stdin and our env variable
-    //arguments:   ['-c', 'echo $@ $ENV_TEST'],
-    environment: ['ENV_TEST='+envTestValue],
-
-    stdin: function(stdin) {
-      stdin.write("echo $ENV_TEST");
-      stdin.close();
-    },
-    stdout: function(data) {
-      test.assert(!gotStdout,"don't get stdout twice");
-      test.assertEqual(data,envTestValue+"\n","stdout contains the environment variable");
-      gotStdout = true;
-    },
-    stderr: function(data) {
-      test.fail("shouldn't get stderr");
-    },
-    done: function() {
-      test.assert(gotStdout, "got stdout before finished");
-      test.done();
-    },
-    mergeStderr: false
-  });
-}
-
-exports.testUnixStderr = function (test) {
-  test.waitUntilDone();
-  let gotStderr = false;
-
-  var p = subprocess.call({
-    // Hope that we don't have to give absolute path on linux ...
-    command:     '/bin/sh',
-    arguments:   ['nonexistent'],
-
-    stdout: function(data) {
-      test.fail("shouldn't get stdout");
-    },
-    stderr: function(data) {
-      test.assert(!gotStderr,"don't get stderr twice");
-      // There is two variant of error message
-      if (data == "/bin/sh: 0: Can't open nonexistent\n")
-        test.pass("stderr containes the expected error message");
-      else
-        test.assertEqual(data, "/bin/sh: nonexistent: No such file or directory\n",
-                         "stderr contains the error message");
-      gotStderr = true;
-    },
-    done: function() {
-      test.assert(gotStderr, "got stderr before finished");
-      test.done();
-    },
-    mergeStderr: false
-  });
-}
-
-}
--- a/configure.in
+++ b/configure.in
@@ -160,30 +160,21 @@ fi
 AC_SUBST(L10NBASEDIR)
 
 dnl Check for Perl first -- needed for win32 SDK checks
 MOZ_PATH_PROGS(PERL, $PERL perl5 perl )
 if test -z "$PERL" -o "$PERL" = ":"; then
     AC_MSG_ERROR([perl not found in \$PATH])
 fi
 
-if test -n "$GAIADIR" -a ! -d "$GAIADIR" ; then
-    AC_MSG_ERROR([GAIADIR '$GAIADIR' isn't a valid directory])
-fi
-
 AC_SUBST(GAIADIR)
 if test -n "$GAIADIR" ; then
     AC_DEFINE(PACKAGE_GAIA)
 fi
 
-if test -n "$FXOS_SIMULATOR" -a -z "$GAIADIR" ; then
-    AC_MSG_ERROR([FXOS_SIMULATOR=1 requires GAIADIR to be defined])
-fi
-AC_SUBST(FXOS_SIMULATOR)
-
 MOZ_ARG_WITH_STRING(gonk,
 [  --with-gonk=DIR
                location of gonk dir],
     gonkdir=$withval)
 
 MOZ_ARG_WITH_STRING(gonk-toolchain-prefix,
 [  --with-gonk-toolchain-prefix=DIR
                           prefix to gonk toolchain commands],
@@ -4245,17 +4236,16 @@ b2g)
   AC_DEFINE(MOZ_B2G)
   ;;
 esac
 
 AC_SUBST(MOZ_BUILD_APP)
 AC_SUBST(MOZ_PHOENIX)
 AC_SUBST(MOZ_XULRUNNER)
 AC_SUBST(MOZ_B2G)
-AC_SUBST(MOZ_B2G_VERSION)
 
 AC_DEFINE_UNQUOTED(MOZ_BUILD_APP,$MOZ_BUILD_APP)
 
 dnl ========================================================
 dnl Check android sdk version depending on mobile target
 dnl ========================================================
 
 if test -z "$gonkdir" ; then