mirror of
https://github.com/fluencelabs/wasmer
synced 2025-05-03 14:22:14 +00:00
Merge #726
726: Add serialization for WASI state r=MarkMcCaskey a=MarkMcCaskey part of #700 Due to the trait objects from #583 , we can't use `serde` derive for this or use serde traits directly, we have to do some custom serialization (edit: luckily there's a crate for this: `typetag`) Co-authored-by: Mark McCaskey <mark@wasmer.io> Co-authored-by: Mark McCaskey <markmccaskey@users.noreply.github.com> Co-authored-by: Syrus Akbary <me@syrusakbary.com>
This commit is contained in:
commit
15066555e7
83
Cargo.lock
generated
83
Cargo.lock
generated
@ -409,6 +409,15 @@ dependencies = [
|
|||||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctor"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@ -467,6 +476,14 @@ dependencies = [
|
|||||||
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "erased-serde"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@ -535,6 +552,7 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -555,6 +573,16 @@ dependencies = [
|
|||||||
"wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ghost"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glob"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
@ -629,6 +657,26 @@ dependencies = [
|
|||||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inventory"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inventory-impl"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -1344,6 +1392,28 @@ name = "typenum"
|
|||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typetag"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typetag-impl"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -1428,7 +1498,9 @@ dependencies = [
|
|||||||
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wabt 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-clif-backend 0.6.0",
|
"wasmer-clif-backend 0.6.0",
|
||||||
"wasmer-dev-utils 0.6.0",
|
"wasmer-dev-utils 0.6.0",
|
||||||
@ -1661,12 +1733,15 @@ dependencies = [
|
|||||||
name = "wasmer-wasi"
|
name = "wasmer-wasi"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-runtime-core 0.6.0",
|
"wasmer-runtime-core 0.6.0",
|
||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -1679,6 +1754,7 @@ dependencies = [
|
|||||||
"wasmer-clif-backend 0.6.0",
|
"wasmer-clif-backend 0.6.0",
|
||||||
"wasmer-dev-utils 0.6.0",
|
"wasmer-dev-utils 0.6.0",
|
||||||
"wasmer-llvm-backend 0.6.0",
|
"wasmer-llvm-backend 0.6.0",
|
||||||
|
"wasmer-runtime 0.6.0",
|
||||||
"wasmer-runtime-core 0.6.0",
|
"wasmer-runtime-core 0.6.0",
|
||||||
"wasmer-singlepass-backend 0.6.0",
|
"wasmer-singlepass-backend 0.6.0",
|
||||||
"wasmer-wasi 0.6.0",
|
"wasmer-wasi 0.6.0",
|
||||||
@ -1812,12 +1888,14 @@ dependencies = [
|
|||||||
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
||||||
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
|
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
|
||||||
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
||||||
|
"checksum ctor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5b6b2f4752cc29efbfd03474c532ce8f916f2d44ec5bb8c21f93bc76e5365528"
|
||||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||||
"checksum dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f36d49ab6f8ecc642d2c6ee10fda04ba68003ef0277300866745cdde160e6b40"
|
"checksum dynasm 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f36d49ab6f8ecc642d2c6ee10fda04ba68003ef0277300866745cdde160e6b40"
|
||||||
"checksum dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c408a211e7f5762829f5e46bdff0c14bc3b1517a21a4bb781c716bf88b0c68"
|
"checksum dynasmrt 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c408a211e7f5762829f5e46bdff0c14bc3b1517a21a4bb781c716bf88b0c68"
|
||||||
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
||||||
"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
|
"checksum enum-methods 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7798e7da2d4cb0d6d6fc467e8d6b5bf247e9e989f786dde1732d79899c32bb10"
|
||||||
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
|
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
|
||||||
|
"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60"
|
||||||
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
|
"checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e"
|
||||||
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
"checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
|
||||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
@ -1829,6 +1907,7 @@ dependencies = [
|
|||||||
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
|
"checksum generational-arena 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4024f96ffa0ebaaf36aa589cd41f2fd69f3a5e6fd02c86e11e12cdf41d5b46a3"
|
||||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||||
"checksum getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6171a6cc63fbabbe27c2b5ee268e8b7fe5dc1eb0dd2dfad537c1dfed6f69117e"
|
"checksum getrandom 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "6171a6cc63fbabbe27c2b5ee268e8b7fe5dc1eb0dd2dfad537c1dfed6f69117e"
|
||||||
|
"checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6"
|
||||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||||
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
"checksum goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e3fa261d919c1ae9d1e4533c4a2f99e10938603c4208d56c05bec7a872b661b0"
|
"checksum goblin 0.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "e3fa261d919c1ae9d1e4533c4a2f99e10938603c4208d56c05bec7a872b661b0"
|
||||||
@ -1838,6 +1917,8 @@ dependencies = [
|
|||||||
"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356"
|
"checksum indexmap 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4d6d89e0948bf10c08b9ecc8ac5b83f07f857ebe2c0cbe38de15b4e4f510356"
|
||||||
"checksum inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
|
"checksum inkwell 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
|
||||||
"checksum inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
|
"checksum inkwell_internal_macros 0.1.0 (git+https://github.com/wasmerio/inkwell?branch=llvm8-0)" = "<none>"
|
||||||
|
"checksum inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299"
|
||||||
|
"checksum inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9"
|
||||||
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
||||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
@ -1925,6 +2006,8 @@ dependencies = [
|
|||||||
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
||||||
"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
|
"checksum toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724"
|
||||||
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
|
"checksum typetag 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebb2c484029d695fb68a06d80e1536c68d491b3e0cf874c66abed255e831cfe"
|
||||||
|
"checksum typetag-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b63fd4799e4d0ec5cf0b055ebb8e2c3a657bbf76a84f6edc77ca60780e000204"
|
||||||
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
|
"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9"
|
||||||
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
|
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
|
||||||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||||||
|
@ -66,6 +66,10 @@ wabt = "0.9.1"
|
|||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
rustc_version = "0.2.3"
|
rustc_version = "0.2.3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde = { version = "1", features = ["derive"] } # used by the plugin example
|
||||||
|
typetag = "0.1" # used by the plugin example
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["fast-tests", "wasi", "backend-cranelift"]
|
default = ["fast-tests", "wasi", "backend-cranelift"]
|
||||||
"loader-kernel" = ["wasmer-kernel-loader"]
|
"loader-kernel" = ["wasmer-kernel-loader"]
|
||||||
|
5
Makefile
5
Makefile
@ -70,12 +70,13 @@ wasitests-singlepass: wasitests-setup
|
|||||||
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features singlepass -- --test-threads=1
|
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features singlepass -- --test-threads=1
|
||||||
|
|
||||||
wasitests-cranelift: wasitests-setup
|
wasitests-cranelift: wasitests-setup
|
||||||
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1
|
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture
|
||||||
|
|
||||||
wasitests-llvm: wasitests-setup
|
wasitests-llvm: wasitests-setup
|
||||||
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features llvm -- --test-threads=1
|
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features llvm -- --test-threads=1
|
||||||
|
|
||||||
wasitests-unit:
|
wasitests-unit: wasitests-setup
|
||||||
|
cargo test --manifest-path lib/wasi-tests/Cargo.toml --release --features clif -- --test-threads=1 --nocapture
|
||||||
cargo test --manifest-path lib/wasi/Cargo.toml --release
|
cargo test --manifest-path lib/wasi/Cargo.toml --release
|
||||||
|
|
||||||
wasitests: wasitests-unit wasitests-singlepass wasitests-cranelift wasitests-llvm
|
wasitests: wasitests-unit wasitests-singlepass wasitests-cranelift wasitests-llvm
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use wasmer_runtime::{func, imports, instantiate};
|
use wasmer_runtime::{func, imports, instantiate};
|
||||||
use wasmer_runtime_core::vm::Ctx;
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
use wasmer_wasi::{
|
use wasmer_wasi::{
|
||||||
@ -13,7 +14,7 @@ fn it_works(_ctx: &mut Ctx) -> i32 {
|
|||||||
5
|
5
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct LoggingWrapper {
|
pub struct LoggingWrapper {
|
||||||
pub wasm_module_name: String,
|
pub wasm_module_name: String,
|
||||||
}
|
}
|
||||||
@ -86,6 +87,8 @@ impl std::io::Write for LoggingWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the WasiFile methods aren't relevant for a write-only Stdout-like implementation
|
// the WasiFile methods aren't relevant for a write-only Stdout-like implementation
|
||||||
|
// we must use typetag and serde so that our trait objects can be safely Serialized and Deserialized
|
||||||
|
#[typetag::serde]
|
||||||
impl WasiFile for LoggingWrapper {
|
impl WasiFile for LoggingWrapper {
|
||||||
fn last_accessed(&self) -> u64 {
|
fn last_accessed(&self) -> u64 {
|
||||||
0
|
0
|
||||||
|
@ -10,6 +10,7 @@ build = "build/mod.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
|
||||||
|
wasmer-runtime = { path = "../runtime", version = "0.6.0" }
|
||||||
wasmer-wasi = { path = "../wasi", version = "0.6.0" }
|
wasmer-wasi = { path = "../wasi", version = "0.6.0" }
|
||||||
# hack to get tests to work
|
# hack to get tests to work
|
||||||
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
|
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.6.0", optional = true }
|
||||||
|
@ -1 +1,60 @@
|
|||||||
// nothing to see here
|
#![cfg(test)]
|
||||||
|
use wasmer_runtime::{compile, Func};
|
||||||
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
|
use wasmer_wasi::{state::*, *};
|
||||||
|
|
||||||
|
use std::ffi::c_void;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serializing_works() {
|
||||||
|
let args = vec![
|
||||||
|
b"program_name".into_iter().cloned().collect(),
|
||||||
|
b"arg1".into_iter().cloned().collect(),
|
||||||
|
];
|
||||||
|
let envs = vec![
|
||||||
|
b"PATH=/bin".into_iter().cloned().collect(),
|
||||||
|
b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
|
||||||
|
];
|
||||||
|
let wasm_binary = include_bytes!("../wasitests/fd_read.wasm");
|
||||||
|
let import_object = generate_import_object(
|
||||||
|
args.clone(),
|
||||||
|
envs.clone(),
|
||||||
|
vec![],
|
||||||
|
vec![(
|
||||||
|
".".to_string(),
|
||||||
|
std::path::PathBuf::from("wasitests/test_fs/hamlet"),
|
||||||
|
)],
|
||||||
|
);
|
||||||
|
let module = compile(&wasm_binary[..])
|
||||||
|
.map_err(|e| format!("Can't compile module: {:?}", e))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let state_bytes = {
|
||||||
|
let instance = module.instantiate(&import_object).unwrap();
|
||||||
|
|
||||||
|
let start: Func<(), ()> = instance.func("_start").unwrap();
|
||||||
|
start.call().unwrap();
|
||||||
|
let state = get_wasi_state(instance.context());
|
||||||
|
|
||||||
|
assert_eq!(state.args, args);
|
||||||
|
assert_eq!(state.envs, envs);
|
||||||
|
let bytes = state.freeze().unwrap();
|
||||||
|
|
||||||
|
bytes
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut instance = module.instantiate(&import_object).unwrap();
|
||||||
|
|
||||||
|
let wasi_state = Box::new(WasiState::unfreeze(&state_bytes).unwrap());
|
||||||
|
|
||||||
|
instance.context_mut().data = Box::into_raw(wasi_state) as *mut c_void;
|
||||||
|
|
||||||
|
let second_entry: Func<(), i32> = instance.func("second_entry").unwrap();
|
||||||
|
let result = second_entry.call().unwrap();
|
||||||
|
assert_eq!(result, true as i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::mut_from_ref)]
|
||||||
|
pub(crate) fn get_wasi_state(ctx: &Ctx) -> &mut WasiState {
|
||||||
|
unsafe { state::get_wasi_state(&mut *(ctx as *const Ctx as *mut Ctx)) }
|
||||||
|
}
|
||||||
|
14
lib/wasi-tests/tests/wasitests/fd_read.rs
Normal file
14
lib/wasi-tests/tests/wasitests/fd_read.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#[test]
|
||||||
|
fn test_fd_read() {
|
||||||
|
assert_wasi_output!(
|
||||||
|
"../../wasitests/fd_read.wasm",
|
||||||
|
"fd_read",
|
||||||
|
vec![],
|
||||||
|
vec![(
|
||||||
|
".".to_string(),
|
||||||
|
::std::path::PathBuf::from("wasitests/test_fs/hamlet")
|
||||||
|
),],
|
||||||
|
vec![],
|
||||||
|
"../../wasitests/fd_read.out"
|
||||||
|
);
|
||||||
|
}
|
@ -9,6 +9,7 @@ mod create_dir;
|
|||||||
mod envvar;
|
mod envvar;
|
||||||
mod fd_allocate;
|
mod fd_allocate;
|
||||||
mod fd_pread;
|
mod fd_pread;
|
||||||
|
mod fd_read;
|
||||||
mod fd_sync;
|
mod fd_sync;
|
||||||
mod file_metadata;
|
mod file_metadata;
|
||||||
mod fs_sandbox_test;
|
mod fs_sandbox_test;
|
||||||
|
3
lib/wasi-tests/wasitests/fd_read.out
Normal file
3
lib/wasi-tests/wasitests/fd_read.out
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SCENE IV. The Queen's closet.
|
||||||
|
|
||||||
|
Enter QUEEN GERTRUDE and POLO
|
86
lib/wasi-tests/wasitests/fd_read.rs
Normal file
86
lib/wasi-tests/wasitests/fd_read.rs
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Args:
|
||||||
|
// mapdir: .:wasitests/test_fs/hamlet
|
||||||
|
|
||||||
|
// this program is used in the pause/resume test
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
use std::os::wasi::prelude::AsRawFd;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
#[repr(C)]
|
||||||
|
struct WasiIovec {
|
||||||
|
pub buf: u32,
|
||||||
|
pub buf_len: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
#[link(wasm_import_module = "wasi_unstable")]
|
||||||
|
extern "C" {
|
||||||
|
fn fd_read(fd: u32, iovs: u32, iovs_len: u32, nread: u32) -> u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
fn read(fd: u32, iovs: &[&mut [u8]]) -> u32 {
|
||||||
|
let mut nread = 0;
|
||||||
|
let mut processed_iovs = vec![];
|
||||||
|
|
||||||
|
for iov in iovs {
|
||||||
|
processed_iovs.push(WasiIovec {
|
||||||
|
buf: iov.as_ptr() as usize as u32,
|
||||||
|
buf_len: iov.len() as u32,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
fd_read(
|
||||||
|
fd,
|
||||||
|
processed_iovs.as_ptr() as usize as u32,
|
||||||
|
processed_iovs.len() as u32,
|
||||||
|
&mut nread as *mut u32 as usize as u32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
nread
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
#[cfg(not(target_os = "wasi"))]
|
||||||
|
let mut base = PathBuf::from("wasitests/test_fs/hamlet");
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
let mut base = PathBuf::from(".");
|
||||||
|
|
||||||
|
base.push("act3/scene4.txt");
|
||||||
|
let mut file = fs::File::open(&base).expect("Could not open file");
|
||||||
|
let mut buffer = [0u8; 64];
|
||||||
|
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
{
|
||||||
|
let raw_fd = file.as_raw_fd();
|
||||||
|
assert_eq!(read(raw_fd, &[&mut buffer]), 64);
|
||||||
|
let str_val = std::str::from_utf8(&buffer[..]).unwrap().to_string();
|
||||||
|
println!("{}", &str_val);
|
||||||
|
}
|
||||||
|
// leak the file handle so that we can use it later
|
||||||
|
std::mem::forget(file);
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "wasi"))]
|
||||||
|
{
|
||||||
|
// eh, just print the output directly
|
||||||
|
print!(
|
||||||
|
"SCENE IV. The Queen's closet.
|
||||||
|
|
||||||
|
Enter QUEEN GERTRUDE and POLO"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "wasi")]
|
||||||
|
#[no_mangle]
|
||||||
|
fn second_entry() -> bool {
|
||||||
|
let raw_fd = 5;
|
||||||
|
let mut buffer = [0u8; 8];
|
||||||
|
let result = read(raw_fd, &[&mut buffer]);
|
||||||
|
|
||||||
|
&buffer == b"NIUS \n\nL"
|
||||||
|
}
|
BIN
lib/wasi-tests/wasitests/fd_read.wasm
Executable file
BIN
lib/wasi-tests/wasitests/fd_read.wasm
Executable file
Binary file not shown.
@ -8,14 +8,17 @@ repository = "https://github.com/wasmerio/wasmer"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
|
bincode = "1"
|
||||||
libc = "0.2.60"
|
|
||||||
rand = "0.7.0"
|
|
||||||
# wasmer-runtime-abi = { path = "../runtime-abi" }
|
|
||||||
generational-arena = "0.2.2"
|
|
||||||
log = "0.4.8"
|
|
||||||
byteorder = "1.3.2"
|
byteorder = "1.3.2"
|
||||||
|
generational-arena = { version = "0.2.2", features = ["serde"] }
|
||||||
|
libc = "0.2.60"
|
||||||
|
log = "0.4.8"
|
||||||
|
rand = "0.7.0"
|
||||||
time = "0.1.42"
|
time = "0.1.42"
|
||||||
|
typetag = "0.1"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
# wasmer-runtime-abi = { path = "../runtime-abi" }
|
||||||
|
wasmer-runtime-core = { path = "../runtime-core", version = "0.6.0" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.3.8"
|
winapi = "0.3.8"
|
||||||
|
@ -44,20 +44,23 @@ pub fn generate_import_object(
|
|||||||
mapped_dirs: Vec<(String, PathBuf)>,
|
mapped_dirs: Vec<(String, PathBuf)>,
|
||||||
) -> ImportObject {
|
) -> ImportObject {
|
||||||
let state_gen = move || {
|
let state_gen = move || {
|
||||||
|
// TODO: look into removing all these unnecessary clones
|
||||||
fn state_destructor(data: *mut c_void) {
|
fn state_destructor(data: *mut c_void) {
|
||||||
unsafe {
|
unsafe {
|
||||||
drop(Box::from_raw(data as *mut WasiState));
|
drop(Box::from_raw(data as *mut WasiState));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let preopened_files = preopened_files.clone();
|
||||||
|
let mapped_dirs = mapped_dirs.clone();
|
||||||
|
|
||||||
let state = Box::new(WasiState {
|
let state = Box::new(WasiState {
|
||||||
fs: WasiFs::new(&preopened_files, &mapped_dirs).unwrap(),
|
fs: WasiFs::new(&preopened_files, &mapped_dirs).expect("Could not create WASI FS"),
|
||||||
args: &args[..],
|
args: args.clone(),
|
||||||
envs: &envs[..],
|
envs: envs.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
(
|
(
|
||||||
Box::leak(state) as *mut WasiState as *mut c_void,
|
Box::into_raw(state) as *mut c_void,
|
||||||
state_destructor as fn(*mut c_void),
|
state_destructor as fn(*mut c_void),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -8,12 +8,13 @@ pub use self::types::*;
|
|||||||
use crate::syscalls::types::*;
|
use crate::syscalls::types::*;
|
||||||
use generational_arena::Arena;
|
use generational_arena::Arena;
|
||||||
pub use generational_arena::Index as Inode;
|
pub use generational_arena::Index as Inode;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
borrow::Borrow,
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
fs,
|
fs,
|
||||||
io::{self, Write},
|
io::Write,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
time::SystemTime,
|
time::SystemTime,
|
||||||
};
|
};
|
||||||
@ -35,7 +36,7 @@ pub unsafe fn get_wasi_state(ctx: &mut Ctx) -> &mut WasiState {
|
|||||||
pub const MAX_SYMLINKS: u32 = 128;
|
pub const MAX_SYMLINKS: u32 = 128;
|
||||||
|
|
||||||
/// A file that Wasi knows about that may or may not be open
|
/// A file that Wasi knows about that may or may not be open
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct InodeVal {
|
pub struct InodeVal {
|
||||||
pub stat: __wasi_filestat_t,
|
pub stat: __wasi_filestat_t,
|
||||||
pub is_preopened: bool,
|
pub is_preopened: bool,
|
||||||
@ -43,26 +44,7 @@ pub struct InodeVal {
|
|||||||
pub kind: Kind,
|
pub kind: Kind,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*impl WasiFdBacking for InodeVal {
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
fn get_stat(&self) -> &__wasi_filestat_t {
|
|
||||||
&self.stat
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_stat_mut(&mut self) -> &mut __wasi_filestat_t {
|
|
||||||
&mut self.stat
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_preopened(&self) -> bool {
|
|
||||||
self.is_preopened
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_name(&self) -> &str {
|
|
||||||
self.name.as_ref()
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Kind {
|
pub enum Kind {
|
||||||
File {
|
File {
|
||||||
/// the open file, if it's open
|
/// the open file, if it's open
|
||||||
@ -106,16 +88,25 @@ pub enum Kind {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Fd {
|
pub struct Fd {
|
||||||
pub rights: __wasi_rights_t,
|
pub rights: __wasi_rights_t,
|
||||||
pub rights_inheriting: __wasi_rights_t,
|
pub rights_inheriting: __wasi_rights_t,
|
||||||
pub flags: __wasi_fdflags_t,
|
pub flags: __wasi_fdflags_t,
|
||||||
pub offset: u64,
|
pub offset: u64,
|
||||||
|
pub open_flags: u16,
|
||||||
pub inode: Inode,
|
pub inode: Inode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl Fd {
|
||||||
|
pub const READ: u16 = 1;
|
||||||
|
pub const WRITE: u16 = 2;
|
||||||
|
pub const APPEND: u16 = 4;
|
||||||
|
pub const TRUNCATE: u16 = 8;
|
||||||
|
pub const CREATE: u16 = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
/// Warning, modifying these fields directly may cause invariants to break and
|
/// Warning, modifying these fields directly may cause invariants to break and
|
||||||
/// should be considered unsafe. These fields may be made private in a future release
|
/// should be considered unsafe. These fields may be made private in a future release
|
||||||
pub struct WasiFs {
|
pub struct WasiFs {
|
||||||
@ -150,9 +141,9 @@ impl WasiFs {
|
|||||||
inode_counter: Cell::new(1024),
|
inode_counter: Cell::new(1024),
|
||||||
orphan_fds: HashMap::new(),
|
orphan_fds: HashMap::new(),
|
||||||
|
|
||||||
stdin: Box::new(Stdin(io::stdin())),
|
stdin: Box::new(Stdin),
|
||||||
stdout: Box::new(Stdout(io::stdout())),
|
stdout: Box::new(Stdout),
|
||||||
stderr: Box::new(Stderr(io::stderr())),
|
stderr: Box::new(Stderr),
|
||||||
};
|
};
|
||||||
// create virtual root
|
// create virtual root
|
||||||
let root_inode = {
|
let root_inode = {
|
||||||
@ -176,8 +167,8 @@ impl WasiFs {
|
|||||||
& (!__WASI_RIGHT_PATH_REMOVE_DIRECTORY)*/;
|
& (!__WASI_RIGHT_PATH_REMOVE_DIRECTORY)*/;
|
||||||
let inode = wasi_fs.create_virtual_root();
|
let inode = wasi_fs.create_virtual_root();
|
||||||
let fd = wasi_fs
|
let fd = wasi_fs
|
||||||
.create_fd(root_rights, root_rights, 0, inode)
|
.create_fd(root_rights, root_rights, 0, Fd::READ, inode)
|
||||||
.expect("Could not create root fd");
|
.map_err(|e| format!("Could not create root fd: {}", e))?;
|
||||||
wasi_fs.preopen_fds.push(fd);
|
wasi_fs.preopen_fds.push(fd);
|
||||||
inode
|
inode
|
||||||
};
|
};
|
||||||
@ -188,7 +179,13 @@ impl WasiFs {
|
|||||||
// TODO: think about this
|
// TODO: think about this
|
||||||
let default_rights = 0x1FFFFFFF; // all rights
|
let default_rights = 0x1FFFFFFF; // all rights
|
||||||
let cur_dir = PathBuf::from(dir);
|
let cur_dir = PathBuf::from(dir);
|
||||||
let cur_dir_metadata = cur_dir.metadata().expect("Could not find directory");
|
let cur_dir_metadata = cur_dir.metadata().map_err(|e| {
|
||||||
|
format!(
|
||||||
|
"Could not get metadata for file {:?}: {}",
|
||||||
|
dir,
|
||||||
|
e.to_string()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let kind = if cur_dir_metadata.is_dir() {
|
let kind = if cur_dir_metadata.is_dir() {
|
||||||
Kind::Dir {
|
Kind::Dir {
|
||||||
parent: Some(root_inode),
|
parent: Some(root_inode),
|
||||||
@ -211,8 +208,14 @@ impl WasiFs {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let fd = wasi_fs
|
let fd = wasi_fs
|
||||||
.create_fd(default_rights, default_rights, 0, inode)
|
.create_fd(
|
||||||
.expect("Could not open fd");
|
default_rights,
|
||||||
|
default_rights,
|
||||||
|
0,
|
||||||
|
Fd::READ | Fd::WRITE,
|
||||||
|
inode,
|
||||||
|
)
|
||||||
|
.map_err(|e| format!("Could not open fd for file {:?}: {}", dir, e))?;
|
||||||
if let Kind::Root { entries } = &mut wasi_fs.inodes[root_inode].kind {
|
if let Kind::Root { entries } = &mut wasi_fs.inodes[root_inode].kind {
|
||||||
// todo handle collisions
|
// todo handle collisions
|
||||||
assert!(entries.insert(dir.to_string(), inode).is_none())
|
assert!(entries.insert(dir.to_string(), inode).is_none())
|
||||||
@ -224,9 +227,13 @@ impl WasiFs {
|
|||||||
debug!("Attempting to open {:?} at {}", real_dir, alias);
|
debug!("Attempting to open {:?} at {}", real_dir, alias);
|
||||||
// TODO: think about this
|
// TODO: think about this
|
||||||
let default_rights = 0x1FFFFFFF; // all rights
|
let default_rights = 0x1FFFFFFF; // all rights
|
||||||
let cur_dir_metadata = real_dir
|
let cur_dir_metadata = real_dir.metadata().map_err(|e| {
|
||||||
.metadata()
|
format!(
|
||||||
.expect("mapped dir not at previously verified location");
|
"Could not get metadata for file {:?}: {}",
|
||||||
|
&real_dir,
|
||||||
|
e.to_string()
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let kind = if cur_dir_metadata.is_dir() {
|
let kind = if cur_dir_metadata.is_dir() {
|
||||||
Kind::Dir {
|
Kind::Dir {
|
||||||
parent: Some(root_inode),
|
parent: Some(root_inode),
|
||||||
@ -249,8 +256,14 @@ impl WasiFs {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let fd = wasi_fs
|
let fd = wasi_fs
|
||||||
.create_fd(default_rights, default_rights, 0, inode)
|
.create_fd(
|
||||||
.expect("Could not open fd");
|
default_rights,
|
||||||
|
default_rights,
|
||||||
|
0,
|
||||||
|
Fd::READ | Fd::WRITE,
|
||||||
|
inode,
|
||||||
|
)
|
||||||
|
.map_err(|e| format!("Could not open fd for file {:?}: {}", &real_dir, e))?;
|
||||||
if let Kind::Root { entries } = &mut wasi_fs.inodes[root_inode].kind {
|
if let Kind::Root { entries } = &mut wasi_fs.inodes[root_inode].kind {
|
||||||
// todo handle collisions
|
// todo handle collisions
|
||||||
assert!(entries.insert(alias.clone(), inode).is_none());
|
assert!(entries.insert(alias.clone(), inode).is_none());
|
||||||
@ -276,6 +289,7 @@ impl WasiFs {
|
|||||||
&mut self,
|
&mut self,
|
||||||
base: __wasi_fd_t,
|
base: __wasi_fd_t,
|
||||||
file: Box<dyn WasiFile>,
|
file: Box<dyn WasiFile>,
|
||||||
|
open_flags: u16,
|
||||||
name: String,
|
name: String,
|
||||||
rights: __wasi_rights_t,
|
rights: __wasi_rights_t,
|
||||||
rights_inheriting: __wasi_rights_t,
|
rights_inheriting: __wasi_rights_t,
|
||||||
@ -312,7 +326,7 @@ impl WasiFs {
|
|||||||
_ => unreachable!("Dir or Root became not Dir or Root"),
|
_ => unreachable!("Dir or Root became not Dir or Root"),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.create_fd(rights, rights_inheriting, flags, inode)
|
self.create_fd(rights, rights_inheriting, flags, open_flags, inode)
|
||||||
.map_err(WasiFsError::from_wasi_err)
|
.map_err(WasiFsError::from_wasi_err)
|
||||||
}
|
}
|
||||||
_ => Err(WasiFsError::BaseNotDirectory),
|
_ => Err(WasiFsError::BaseNotDirectory),
|
||||||
@ -754,10 +768,13 @@ impl WasiFs {
|
|||||||
let inode = &mut self.inodes[fd.inode];
|
let inode = &mut self.inodes[fd.inode];
|
||||||
|
|
||||||
match &mut inode.kind {
|
match &mut inode.kind {
|
||||||
Kind::File {
|
Kind::File { handle, .. } => {
|
||||||
handle: Some(handle),
|
if let Some(file) = handle {
|
||||||
..
|
file.flush().map_err(|_| __WASI_EIO)?
|
||||||
} => handle.flush().map_err(|_| __WASI_EIO)?,
|
} else {
|
||||||
|
return Err(__WASI_EIO);
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: verify this behavior
|
// TODO: verify this behavior
|
||||||
Kind::Dir { .. } => return Err(__WASI_EISDIR),
|
Kind::Dir { .. } => return Err(__WASI_EISDIR),
|
||||||
Kind::Symlink { .. } => unimplemented!(),
|
Kind::Symlink { .. } => unimplemented!(),
|
||||||
@ -810,6 +827,7 @@ impl WasiFs {
|
|||||||
rights: __wasi_rights_t,
|
rights: __wasi_rights_t,
|
||||||
rights_inheriting: __wasi_rights_t,
|
rights_inheriting: __wasi_rights_t,
|
||||||
flags: __wasi_fdflags_t,
|
flags: __wasi_fdflags_t,
|
||||||
|
open_flags: u16,
|
||||||
inode: Inode,
|
inode: Inode,
|
||||||
) -> Result<__wasi_fd_t, __wasi_errno_t> {
|
) -> Result<__wasi_fd_t, __wasi_errno_t> {
|
||||||
let idx = self.next_fd.get();
|
let idx = self.next_fd.get();
|
||||||
@ -821,6 +839,7 @@ impl WasiFs {
|
|||||||
rights_inheriting,
|
rights_inheriting,
|
||||||
flags,
|
flags,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
open_flags,
|
||||||
inode,
|
inode,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -924,11 +943,23 @@ impl WasiFs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct WasiState<'a> {
|
pub struct WasiState {
|
||||||
pub fs: WasiFs,
|
pub fs: WasiFs,
|
||||||
pub args: &'a [Vec<u8>],
|
pub args: Vec<Vec<u8>>,
|
||||||
pub envs: &'a [Vec<u8>],
|
pub envs: Vec<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasiState {
|
||||||
|
/// Turn the WasiState into bytes
|
||||||
|
pub fn freeze(&self) -> Option<Vec<u8>> {
|
||||||
|
bincode::serialize(self).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a WasiState from bytes
|
||||||
|
pub fn unfreeze(bytes: &[u8]) -> Option<Self> {
|
||||||
|
bincode::deserialize(bytes).ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn host_file_type_to_wasi_file_type(file_type: fs::FileType) -> __wasi_filetype_t {
|
pub fn host_file_type_to_wasi_file_type(file_type: fs::FileType) -> __wasi_filetype_t {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/// types for use in the WASI filesystem
|
/// types for use in the WASI filesystem
|
||||||
use crate::syscalls::types::*;
|
use crate::syscalls::types::*;
|
||||||
|
use serde::{de, Deserialize, Serialize};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::{
|
use std::{
|
||||||
@ -117,6 +118,7 @@ impl WasiFsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This trait relies on your file closing when it goes out of scope via `Drop`
|
/// This trait relies on your file closing when it goes out of scope via `Drop`
|
||||||
|
#[typetag::serde(tag = "type")]
|
||||||
pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
|
pub trait WasiFile: std::fmt::Debug + Write + Read + Seek {
|
||||||
/// the last time the file was accessed in nanoseconds as a UNIX timestamp
|
/// the last time the file was accessed in nanoseconds as a UNIX timestamp
|
||||||
fn last_accessed(&self) -> __wasi_timestamp_t;
|
fn last_accessed(&self) -> __wasi_timestamp_t;
|
||||||
@ -339,18 +341,122 @@ pub(crate) fn poll(
|
|||||||
pub trait WasiPath {}
|
pub trait WasiPath {}
|
||||||
|
|
||||||
/// A thin wrapper around `std::fs::File`
|
/// A thin wrapper around `std::fs::File`
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct HostFile {
|
pub struct HostFile {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
pub inner: fs::File,
|
pub inner: fs::File,
|
||||||
pub host_path: PathBuf,
|
pub host_path: PathBuf,
|
||||||
|
flags: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for HostFile {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<HostFile, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(field_identifier, rename_all = "snake_case")]
|
||||||
|
enum Field {
|
||||||
|
HostPath,
|
||||||
|
Flags,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HostFileVisitor;
|
||||||
|
|
||||||
|
impl<'de> de::Visitor<'de> for HostFileVisitor {
|
||||||
|
type Value = HostFile;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("struct HostFile")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
|
||||||
|
where
|
||||||
|
V: de::SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let host_path = seq
|
||||||
|
.next_element()?
|
||||||
|
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
|
||||||
|
let flags = seq
|
||||||
|
.next_element()?
|
||||||
|
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
|
||||||
|
let inner = std::fs::OpenOptions::new()
|
||||||
|
.read(flags & HostFile::READ != 0)
|
||||||
|
.write(flags & HostFile::WRITE != 0)
|
||||||
|
.append(flags & HostFile::APPEND != 0)
|
||||||
|
.open(&host_path)
|
||||||
|
.map_err(|_| de::Error::custom("Could not open file on this system"))?;
|
||||||
|
Ok(HostFile {
|
||||||
|
inner,
|
||||||
|
host_path,
|
||||||
|
flags,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
|
||||||
|
where
|
||||||
|
V: de::MapAccess<'de>,
|
||||||
|
{
|
||||||
|
let mut host_path = None;
|
||||||
|
let mut flags = None;
|
||||||
|
while let Some(key) = map.next_key()? {
|
||||||
|
match key {
|
||||||
|
Field::HostPath => {
|
||||||
|
if host_path.is_some() {
|
||||||
|
return Err(de::Error::duplicate_field("host_path"));
|
||||||
|
}
|
||||||
|
host_path = Some(map.next_value()?);
|
||||||
|
}
|
||||||
|
Field::Flags => {
|
||||||
|
if flags.is_some() {
|
||||||
|
return Err(de::Error::duplicate_field("flags"));
|
||||||
|
}
|
||||||
|
flags = Some(map.next_value()?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let host_path = host_path.ok_or_else(|| de::Error::missing_field("host_path"))?;
|
||||||
|
let flags = flags.ok_or_else(|| de::Error::missing_field("flags"))?;
|
||||||
|
let inner = std::fs::OpenOptions::new()
|
||||||
|
.read(flags & HostFile::READ != 0)
|
||||||
|
.write(flags & HostFile::WRITE != 0)
|
||||||
|
.append(flags & HostFile::APPEND != 0)
|
||||||
|
.open(&host_path)
|
||||||
|
.map_err(|_| de::Error::custom("Could not open file on this system"))?;
|
||||||
|
Ok(HostFile {
|
||||||
|
inner,
|
||||||
|
host_path,
|
||||||
|
flags,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FIELDS: &'static [&'static str] = &["host_path", "flags"];
|
||||||
|
deserializer.deserialize_struct("HostFile", FIELDS, HostFileVisitor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HostFile {
|
impl HostFile {
|
||||||
|
const READ: u16 = 1;
|
||||||
|
const WRITE: u16 = 2;
|
||||||
|
const APPEND: u16 = 4;
|
||||||
|
|
||||||
/// creates a new host file from a `std::fs::File` and a path
|
/// creates a new host file from a `std::fs::File` and a path
|
||||||
pub fn new(file: fs::File, host_path: PathBuf) -> Self {
|
pub fn new(file: fs::File, host_path: PathBuf, read: bool, write: bool, append: bool) -> Self {
|
||||||
|
let mut flags = 0;
|
||||||
|
if read {
|
||||||
|
flags |= Self::READ;
|
||||||
|
}
|
||||||
|
if write {
|
||||||
|
flags |= Self::WRITE;
|
||||||
|
}
|
||||||
|
if append {
|
||||||
|
flags |= Self::APPEND;
|
||||||
|
}
|
||||||
Self {
|
Self {
|
||||||
inner: file,
|
inner: file,
|
||||||
host_path,
|
host_path,
|
||||||
|
flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +499,7 @@ impl Write for HostFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
impl WasiFile for HostFile {
|
impl WasiFile for HostFile {
|
||||||
fn last_accessed(&self) -> u64 {
|
fn last_accessed(&self) -> u64 {
|
||||||
self.metadata()
|
self.metadata()
|
||||||
@ -519,57 +626,55 @@ fn host_file_bytes_available(_raw_fd: i32) -> Result<usize, WasiFsError> {
|
|||||||
unimplemented!("host_file_bytes_available not yet implemented for non-Unix-like targets. This probably means the program tried to use wasi::poll_oneoff")
|
unimplemented!("host_file_bytes_available not yet implemented for non-Unix-like targets. This probably means the program tried to use wasi::poll_oneoff")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Stdout(pub std::io::Stdout);
|
pub struct Stdout;
|
||||||
impl Read for Stdout {
|
impl Read for Stdout {
|
||||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stdout",
|
"can not read from stdout",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
|
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stdout",
|
"can not read from stdout",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stdout",
|
"can not read from stdout",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stdout",
|
"can not read from stdout",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Seek for Stdout {
|
impl Seek for Stdout {
|
||||||
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not seek stdout"))
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"can not seek stdout",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Write for Stdout {
|
impl Write for Stdout {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
io::stdout().write(buf)
|
||||||
}
|
}
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
self.0.flush()
|
io::stdout().flush()
|
||||||
}
|
}
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||||
self.0.write_all(buf)
|
io::stdout().write_all(buf)
|
||||||
}
|
}
|
||||||
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
||||||
self.0.write_fmt(fmt)
|
io::stdout().write_fmt(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
impl WasiFile for Stdout {
|
impl WasiFile for Stdout {
|
||||||
fn last_accessed(&self) -> u64 {
|
fn last_accessed(&self) -> u64 {
|
||||||
0
|
0
|
||||||
@ -594,7 +699,7 @@ impl WasiFile for Stdout {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn get_raw_fd(&self) -> Option<i32> {
|
fn get_raw_fd(&self) -> Option<i32> {
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
Some(self.0.as_raw_fd())
|
Some(io::stdout().as_raw_fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
@ -605,57 +710,55 @@ impl WasiFile for Stdout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Stderr(pub std::io::Stderr);
|
pub struct Stderr;
|
||||||
impl Read for Stderr {
|
impl Read for Stderr {
|
||||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stderr",
|
"can not read from stderr",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
|
fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stderr",
|
"can not read from stderr",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stderr",
|
"can not read from stderr",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
fn read_exact(&mut self, _buf: &mut [u8]) -> io::Result<()> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not read from stderr",
|
"can not read from stderr",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Seek for Stderr {
|
impl Seek for Stderr {
|
||||||
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not seek stderr"))
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"can not seek stderr",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Write for Stderr {
|
impl Write for Stderr {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
self.0.write(buf)
|
io::stderr().write(buf)
|
||||||
}
|
}
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
self.0.flush()
|
io::stderr().flush()
|
||||||
}
|
}
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||||
self.0.write_all(buf)
|
io::stderr().write_all(buf)
|
||||||
}
|
}
|
||||||
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
fn write_fmt(&mut self, fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
||||||
self.0.write_fmt(fmt)
|
io::stderr().write_fmt(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
impl WasiFile for Stderr {
|
impl WasiFile for Stderr {
|
||||||
fn last_accessed(&self) -> u64 {
|
fn last_accessed(&self) -> u64 {
|
||||||
0
|
0
|
||||||
@ -680,7 +783,7 @@ impl WasiFile for Stderr {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn get_raw_fd(&self) -> Option<i32> {
|
fn get_raw_fd(&self) -> Option<i32> {
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
Some(self.0.as_raw_fd())
|
Some(io::stderr().as_raw_fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
@ -691,57 +794,55 @@ impl WasiFile for Stderr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Stdin(pub std::io::Stdin);
|
pub struct Stdin;
|
||||||
impl Read for Stdin {
|
impl Read for Stdin {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
self.0.read(buf)
|
io::stdin().read(buf)
|
||||||
}
|
}
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||||
self.0.read_to_end(buf)
|
io::stdin().read_to_end(buf)
|
||||||
}
|
}
|
||||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
self.0.read_to_string(buf)
|
io::stdin().read_to_string(buf)
|
||||||
}
|
}
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||||
self.0.read_exact(buf)
|
io::stdin().read_exact(buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Seek for Stdin {
|
impl Seek for Stdin {
|
||||||
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
fn seek(&mut self, _pos: io::SeekFrom) -> io::Result<u64> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(io::ErrorKind::Other, "can not seek stdin"))
|
||||||
std::io::ErrorKind::Other,
|
|
||||||
"can not seek stdin",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Write for Stdin {
|
impl Write for Stdin {
|
||||||
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not write to stdin",
|
"can not write to stdin",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn flush(&mut self) -> io::Result<()> {
|
fn flush(&mut self) -> io::Result<()> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not write to stdin",
|
"can not write to stdin",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
|
fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not write to stdin",
|
"can not write to stdin",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
fn write_fmt(&mut self, _fmt: ::std::fmt::Arguments) -> io::Result<()> {
|
||||||
Err(std::io::Error::new(
|
Err(io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"can not write to stdin",
|
"can not write to stdin",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[typetag::serde]
|
||||||
impl WasiFile for Stdin {
|
impl WasiFile for Stdin {
|
||||||
fn last_accessed(&self) -> u64 {
|
fn last_accessed(&self) -> u64 {
|
||||||
0
|
0
|
||||||
@ -766,7 +867,7 @@ impl WasiFile for Stdin {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn get_raw_fd(&self) -> Option<i32> {
|
fn get_raw_fd(&self) -> Option<i32> {
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
Some(self.0.as_raw_fd())
|
Some(io::stdin().as_raw_fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
|
@ -689,23 +689,11 @@ pub fn fd_pread(
|
|||||||
match &mut state.fs.inodes[inode].kind {
|
match &mut state.fs.inodes[inode].kind {
|
||||||
Kind::File { handle, .. } => {
|
Kind::File { handle, .. } => {
|
||||||
if let Some(h) = handle {
|
if let Some(h) = handle {
|
||||||
let current_pos =
|
|
||||||
wasi_try!(h.seek(std::io::SeekFrom::Current(0)).ok(), __WASI_EIO);
|
|
||||||
wasi_try!(
|
wasi_try!(
|
||||||
h.seek(std::io::SeekFrom::Start(offset as u64)).ok(),
|
h.seek(std::io::SeekFrom::Start(offset as u64)).ok(),
|
||||||
__WASI_EIO
|
__WASI_EIO
|
||||||
);
|
);
|
||||||
let bytes_read = wasi_try!(read_bytes(h, memory, iov_cells));
|
let bytes_read = wasi_try!(read_bytes(h, memory, iov_cells));
|
||||||
// reborrow so we can seek it back (the &mut gets moved into `read_bytes`
|
|
||||||
// and we can't use it after)
|
|
||||||
// If you're in the future and there's a nicer way to do this, please
|
|
||||||
// clean up this code
|
|
||||||
if let Some(h) = handle {
|
|
||||||
wasi_try!(
|
|
||||||
h.seek(std::io::SeekFrom::Start(current_pos)).ok(),
|
|
||||||
__WASI_EIO
|
|
||||||
);
|
|
||||||
}
|
|
||||||
bytes_read
|
bytes_read
|
||||||
} else {
|
} else {
|
||||||
return __WASI_EINVAL;
|
return __WASI_EINVAL;
|
||||||
@ -1681,6 +1669,7 @@ pub fn path_open(
|
|||||||
if let Ok(m) = maybe_inode {
|
if let Ok(m) = maybe_inode {
|
||||||
&state.fs.inodes[m];
|
&state.fs.inodes[m];
|
||||||
}
|
}
|
||||||
|
let mut open_flags = 0;
|
||||||
|
|
||||||
// TODO: traverse rights of dirs properly
|
// TODO: traverse rights of dirs properly
|
||||||
// COMMENTED OUT: WASI isn't giving appropriate rights here when opening
|
// COMMENTED OUT: WASI isn't giving appropriate rights here when opening
|
||||||
@ -1708,10 +1697,22 @@ pub fn path_open(
|
|||||||
.write(adjusted_rights & __WASI_RIGHT_FD_WRITE != 0)
|
.write(adjusted_rights & __WASI_RIGHT_FD_WRITE != 0)
|
||||||
.create(o_flags & __WASI_O_CREAT != 0)
|
.create(o_flags & __WASI_O_CREAT != 0)
|
||||||
.truncate(o_flags & __WASI_O_TRUNC != 0);
|
.truncate(o_flags & __WASI_O_TRUNC != 0);
|
||||||
|
open_flags |= Fd::READ;
|
||||||
|
if adjusted_rights & __WASI_RIGHT_FD_WRITE != 0 {
|
||||||
|
open_flags |= Fd::WRITE;
|
||||||
|
}
|
||||||
|
if o_flags & __WASI_O_CREAT != 0 {
|
||||||
|
open_flags |= Fd::CREATE;
|
||||||
|
}
|
||||||
|
if o_flags & __WASI_O_TRUNC != 0 {
|
||||||
|
open_flags |= Fd::TRUNCATE;
|
||||||
|
}
|
||||||
*handle = Some(Box::new(HostFile::new(
|
*handle = Some(Box::new(HostFile::new(
|
||||||
wasi_try!(open_options.open(&path).map_err(|_| __WASI_EIO)),
|
wasi_try!(open_options.open(&path).map_err(|_| __WASI_EIO)),
|
||||||
path.to_path_buf(),
|
path.to_path_buf(),
|
||||||
|
true,
|
||||||
|
adjusted_rights & __WASI_RIGHT_FD_WRITE != 0,
|
||||||
|
false,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
Kind::Buffer { .. } => unimplemented!("wasi::path_open for Buffer type files"),
|
Kind::Buffer { .. } => unimplemented!("wasi::path_open for Buffer type files"),
|
||||||
@ -1768,6 +1769,7 @@ pub fn path_open(
|
|||||||
// write access is required for creating a file
|
// write access is required for creating a file
|
||||||
.write(true)
|
.write(true)
|
||||||
.create_new(true);
|
.create_new(true);
|
||||||
|
open_flags |= Fd::READ | Fd::WRITE | Fd::CREATE | Fd::TRUNCATE;
|
||||||
|
|
||||||
Some(Box::new(HostFile::new(
|
Some(Box::new(HostFile::new(
|
||||||
wasi_try!(open_options.open(&new_file_host_path).map_err(|e| {
|
wasi_try!(open_options.open(&new_file_host_path).map_err(|e| {
|
||||||
@ -1775,6 +1777,9 @@ pub fn path_open(
|
|||||||
__WASI_EIO
|
__WASI_EIO
|
||||||
})),
|
})),
|
||||||
new_file_host_path.clone(),
|
new_file_host_path.clone(),
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
)) as Box<dyn WasiFile>)
|
)) as Box<dyn WasiFile>)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1806,10 +1811,13 @@ pub fn path_open(
|
|||||||
|
|
||||||
// TODO: check and reduce these
|
// TODO: check and reduce these
|
||||||
// TODO: ensure a mutable fd to root can never be opened
|
// TODO: ensure a mutable fd to root can never be opened
|
||||||
let out_fd =
|
let out_fd = wasi_try!(state.fs.create_fd(
|
||||||
wasi_try!(state
|
adjusted_rights,
|
||||||
.fs
|
fs_rights_inheriting,
|
||||||
.create_fd(adjusted_rights, fs_rights_inheriting, fs_flags, inode));
|
fs_flags,
|
||||||
|
open_flags,
|
||||||
|
inode
|
||||||
|
));
|
||||||
|
|
||||||
fd_cell.set(out_fd);
|
fd_cell.set(out_fd);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use crate::ptr::{Array, WasmPtr};
|
use crate::ptr::{Array, WasmPtr};
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use wasmer_runtime_core::types::ValueType;
|
use wasmer_runtime_core::types::ValueType;
|
||||||
@ -316,7 +317,7 @@ pub type __wasi_filedelta_t = i64;
|
|||||||
|
|
||||||
pub type __wasi_filesize_t = u64;
|
pub type __wasi_filesize_t = u64;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct __wasi_filestat_t {
|
pub struct __wasi_filestat_t {
|
||||||
pub st_dev: __wasi_device_t,
|
pub st_dev: __wasi_device_t,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user