aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS12
-rw-r--r--src/library.js16
-rw-r--r--src/postamble.js12
-rw-r--r--src/settings.js4
-rw-r--r--tests/runner.py13
-rw-r--r--tools/shared.py2
6 files changed, 46 insertions, 13 deletions
diff --git a/AUTHORS b/AUTHORS
index 3686eac2..27323682 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,14 +9,4 @@ under the licensing terms detailed in LICENSE.
* Benoit Tremblay <benoit.tremblay@frimastudio.com>
* Andreas Bergmeier <andreas.bergmeier@gmx.net>
* Ben Schwartz <bens@alum.mit.edu>
-
-
-
-
-
-
-
-
-
-
-
+* David Claughton <dave@eclecticdave.com>
diff --git a/src/library.js b/src/library.js
index 113c955c..1f63e6d0 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1752,9 +1752,25 @@ LibraryManager.library = {
_exit: function(status) {
// void _exit(int status);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
+
+#if CATCH_EXIT_CODE
+ function ExitStatus() {
+ this.name = "ExitStatus";
+ this.message = "Program terminated with exit(" + status + ")";
+ this.status = status;
+ };
+ ExitStatus.prototype = new Error();
+ ExitStatus.prototype.constructor = ExitStatus;
+#endif
+
__shutdownRuntime__();
ABORT = true;
+
+#if CATCH_EXIT_CODE
+ throw new ExitStatus();
+#else
throw 'exit(' + status + ') called, at ' + new Error().stack;
+#endif
},
fork__deps: ['__setErrNo', '$ERRNO_CODES'],
fork: function() {
diff --git a/src/postamble.js b/src/postamble.js
index c8fd44bd..51ffc6ee 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -17,7 +17,14 @@ Module.callMain = function callMain(args) {
argv.push(0);
argv = allocate(argv, 'i32', ALLOC_STATIC);
+#if CATCH_EXIT_CODE
+ try {
+ return _main(argc, argv, 0);
+ }
+ catch(e) { if (e.name == "ExitStatus") return e.status; throw e; }
+#else
return _main(argc, argv, 0);
+#endif
}
{{GLOBAL_VARS}}
@@ -49,7 +56,10 @@ Module['noInitialRun'] = true;
#endif
if (!Module['noInitialRun']) {
- run();
+ var ret = run();
+#if CATCH_EXIT_CODE
+ print('Exit Status: ' + ret);
+#endif
}
// {{POST_RUN_ADDITIONS}}
diff --git a/src/settings.js b/src/settings.js
index bcda4757..66762298 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -77,6 +77,10 @@ var CLOSURE_INLINE_PREVENTION_LINES = 50; // Functions of this number of lines o
// code generated that tells the closure compiler not to
// inline them. This is useful to prevent the generation of
// overly large functions.
+var CATCH_EXIT_CODE = 0; // If set, causes exit() to throw an exception object which is caught
+ // in a try..catch block and results in the exit status being
+ // returned from run(). If zero (the default), the program is just
+ // terminated with an error message.
// Generated code debugging options
var SAFE_HEAP = 0; // Check each write to the heap against a list of blocked addresses
diff --git a/tests/runner.py b/tests/runner.py
index ea2025b7..bd01d6d2 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -4533,6 +4533,19 @@ Child2:9
except:
pass
+ def test_exit_status(self):
+ Settings.CATCH_EXIT_CODE = 1
+
+ src = '''
+ #include <stdio.h>
+ #include <stdlib.h>
+ int main()
+ {
+ printf("hello, world!\\n");
+ exit(118); // Unusual exit status to make sure it's working!
+ }
+ '''
+ self.do_run(src, 'hello, world!\nExit Status: 118')
# Generate tests for all our compilers
def make_run(name, compiler, llvm_opts, embetter, quantum_size, typed_arrays):
diff --git a/tools/shared.py b/tools/shared.py
index 06c69f83..f6a03c6c 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -275,7 +275,7 @@ class Building:
# Run Emscripten
exported_settings = {}
- for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES']:
+ for setting in ['QUANTUM_SIZE', 'RELOOP', 'MICRO_OPTS', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'PGO', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTION_CATCHING', 'TOTAL_MEMORY', 'FAST_MEMORY', 'EXCEPTION_DEBUG', 'PROFILE', 'I64_MODE', 'EMULATE_UNALIGNED_ACCESSES', 'CATCH_EXIT_CODE']:
try:
value = eval('Settings.' + setting)
if value is not None: