]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: on wasm, do not panic if "process" global is not defined
authorRichard Musiol <mail@richard-musiol.de>
Mon, 7 Oct 2019 22:58:26 +0000 (00:58 +0200)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 8 Oct 2019 02:42:57 +0000 (02:42 +0000)
When running wasm in the browser, the "process" global is not defined.
This causes functions like os.Getpid() to panic, which is unusual.
For example on Windows os.Getpid() returns -1 and does not panic.

This change adds a dummy polyfill for "process" which returns -1 or an
error. It also extends the polyfill for "fs".

Fixes #34627
Replaces CL 199357

Change-Id: Ifeb12fe7e152c517848933a9ab5f6f749896dcef
Reviewed-on: https://go-review.googlesource.com/c/go/+/199698
Run-TryBot: Richard Musiol <neelance@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
misc/wasm/wasm_exec.js
src/syscall/syscall_js.go

index 9ffa9201e87052570c08590e0ae0a3d596b2cd76..3c2c1868679e8ebcba195de1231d6f320737c6e5 100644 (file)
                global.fs = require("fs");
        }
 
+       const enosys = () => {
+               const err = new Error("not implemented");
+               err.code = "ENOSYS";
+               return err;
+       };
+
        if (!global.fs) {
                let outputBuf = "";
                global.fs = {
                        },
                        write(fd, buf, offset, length, position, callback) {
                                if (offset !== 0 || length !== buf.length || position !== null) {
-                                       throw new Error("not implemented");
+                                       callback(enosys());
+                                       return;
                                }
                                const n = this.writeSync(fd, buf);
                                callback(null, n);
                        },
-                       open(path, flags, mode, callback) {
-                               const err = new Error("not implemented");
-                               err.code = "ENOSYS";
-                               callback(err);
-                       },
-                       read(fd, buffer, offset, length, position, callback) {
-                               const err = new Error("not implemented");
-                               err.code = "ENOSYS";
-                               callback(err);
-                       },
-                       fsync(fd, callback) {
-                               callback(null);
-                       },
+                       chmod(path, mode, callback) { callback(enosys()); },
+                       chown(path, uid, gid, callback) { callback(enosys()); },
+                       close(fd, callback) { callback(enosys()); },
+                       fchmod(fd, mode, callback) { callback(enosys()); },
+                       fchown(fd, uid, gid, callback) { callback(enosys()); },
+                       fstat(fd, callback) { callback(enosys()); },
+                       fsync(fd, callback) { callback(null); },
+                       ftruncate(fd, length, callback) { callback(enosys()); },
+                       lchown(path, uid, gid, callback) { callback(enosys()); },
+                       link(path, link, callback) { callback(enosys()); },
+                       lstat(path, callback) { callback(enosys()); },
+                       mkdir(path, perm, callback) { callback(enosys()); },
+                       open(path, flags, mode, callback) { callback(enosys()); },
+                       read(fd, buffer, offset, length, position, callback) { callback(enosys()); },
+                       readdir(path, callback) { callback(enosys()); },
+                       readlink(path, callback) { callback(enosys()); },
+                       rename(from, to, callback) { callback(enosys()); },
+                       rmdir(path, callback) { callback(enosys()); },
+                       stat(path, callback) { callback(enosys()); },
+                       symlink(path, link, callback) { callback(enosys()); },
+                       truncate(path, length, callback) { callback(enosys()); },
+                       unlink(path, callback) { callback(enosys()); },
+                       utimes(path, atime, mtime, callback) { callback(enosys()); },
                };
        }
 
+       if (!global.process) {
+               global.process = {
+                       getuid() { return -1; },
+                       getgid() { return -1; },
+                       geteuid() { return -1; },
+                       getegid() { return -1; },
+                       getgroups() { throw enosys(); },
+                       pid: -1,
+                       ppid: -1,
+                       umask() { throw enosys(); },
+                       cwd() { throw enosys(); },
+                       chdir() { throw enosys(); },
+               }
+       }
+
        if (!global.crypto) {
                const nodeCrypto = require("crypto");
                global.crypto = {
index 987dd4a79615aa3d079fcb0d1a0d336fda80dfd4..dfb4a275e30fd807ad3422bc7d4cedee6f73e796 100644 (file)
@@ -303,9 +303,10 @@ func Getegid() int {
        return jsProcess.Call("getegid").Int()
 }
 
-func Getgroups() ([]int, error) {
+func Getgroups() (groups []int, err error) {
+       defer recoverErr(&err)
        array := jsProcess.Call("getgroups")
-       groups := make([]int, array.Length())
+       groups = make([]int, array.Length())
        for i := range groups {
                groups[i] = array.Index(i).Int()
        }