From b80abdc5a6c8664ed3f2ba92430269b46dee51f2 Mon Sep 17 00:00:00 2001 From: Kelvin Nishikawa Date: Tue, 26 Nov 2024 13:17:25 -0800 Subject: [PATCH 1/2] Fixing some WASIp1 functions --- Wacs.WASIp1/FileUtil.cs | 2 +- Wacs.WASIp1/FsFdStat.cs | 49 +++++++++++++++-------- Wacs.WASIp1/Sock.cs | 68 ++++++++++++++++++++++++++++++++ Wacs.WASIp1/State.cs | 6 +++ Wacs.WASIp1/Types/RiFlags.cs | 31 +++++++++++++++ Wacs.WASIp1/Types/RoFlags.cs | 30 ++++++++++++++ Wacs.WASIp1/Types/SdFlags.cs | 31 +++++++++++++++ Wacs.WASIp1/Types/SiFlags.cs | 29 ++++++++++++++ Wacs.WASIp1/VirtualPathMapper.cs | 3 ++ Wacs.WASIp1/Wasi.cs | 8 +++- 10 files changed, 238 insertions(+), 19 deletions(-) create mode 100644 Wacs.WASIp1/Sock.cs create mode 100644 Wacs.WASIp1/Types/RiFlags.cs create mode 100644 Wacs.WASIp1/Types/RoFlags.cs create mode 100644 Wacs.WASIp1/Types/SdFlags.cs create mode 100644 Wacs.WASIp1/Types/SiFlags.cs diff --git a/Wacs.WASIp1/FileUtil.cs b/Wacs.WASIp1/FileUtil.cs index fa9ee4b..c48673e 100644 --- a/Wacs.WASIp1/FileUtil.cs +++ b/Wacs.WASIp1/FileUtil.cs @@ -29,7 +29,7 @@ public static ulong GenerateInode(FileInfo fileInfo) using (var sha256 = SHA256.Create()) { // Combine file attributes - string data = $"{fileInfo.FullName}|{fileInfo.CreationTimeUtc.Ticks}|{fileInfo.Length}"; + string data = $"{fileInfo.FullName}|{fileInfo.CreationTimeUtc.Ticks}|{(fileInfo.Exists ? fileInfo.Length : 0L)}"; byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(data)); // Use the first 8 bytes of the hash as the inode ulong inode = BitConverter.ToUInt64(hashBytes, 0); diff --git a/Wacs.WASIp1/FsFdStat.cs b/Wacs.WASIp1/FsFdStat.cs index 1e8bb9f..30dec4d 100644 --- a/Wacs.WASIp1/FsFdStat.cs +++ b/Wacs.WASIp1/FsFdStat.cs @@ -128,23 +128,40 @@ public ErrNo FdFilestatGet(ExecContext ctx, fd fd, ptr bufPtr) if (!GetFd(fd, out var fileDescriptor)) return ErrNo.NoEnt; - var hostPath = _state.PathMapper.MapToHostPath(fileDescriptor.Path); - var fileInfo = new FileInfo(hostPath); - - var fileStat = new FileStat + if (fd < 3) { - Device = 0, // Device ID - can be set later if available - Ino = FileUtil.GenerateInode(fileInfo), - Mode = fileDescriptor.Type, - NLink = 1, // Number of hard links - can be adjusted as needed - Size = (filesize)fileInfo.Length, - ATim = Clock.ToTimestamp(fileInfo.LastAccessTimeUtc), - MTim = Clock.ToTimestamp(fileInfo.LastWriteTimeUtc), - CTim = Clock.ToTimestamp(fileInfo.CreationTimeUtc) - }; - - mem.WriteStruct(bufPtr, ref fileStat); - + var fileStat = new FileStat + { + Device = 0, // Device ID - can be set later if available + Ino = fd, + Mode = fileDescriptor.Type, + NLink = 1, // Number of hard links - can be adjusted as needed + Size = 0, + ATim = 0, + MTim = 0, + CTim = 0, + }; + + mem.WriteStruct(bufPtr, ref fileStat); + } + else + { + var hostPath = _state.PathMapper.MapToHostPath(fileDescriptor.Path); + var fileInfo = new FileInfo(hostPath); + var fileStat = new FileStat + { + Device = 0, // Device ID - can be set later if available + Ino = FileUtil.GenerateInode(fileInfo), + Mode = fileDescriptor.Type, + NLink = 1, // Number of hard links - can be adjusted as needed + Size = (filesize)fileInfo.Length, + ATim = Clock.ToTimestamp(fileInfo.LastAccessTimeUtc), + MTim = Clock.ToTimestamp(fileInfo.LastWriteTimeUtc), + CTim = Clock.ToTimestamp(fileInfo.CreationTimeUtc) + }; + + mem.WriteStruct(bufPtr, ref fileStat); + } return ErrNo.Success; } diff --git a/Wacs.WASIp1/Sock.cs b/Wacs.WASIp1/Sock.cs new file mode 100644 index 0000000..2342ed6 --- /dev/null +++ b/Wacs.WASIp1/Sock.cs @@ -0,0 +1,68 @@ +// /* +// * Copyright 2024 Kelvin Nishikawa +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +using System; +using Wacs.Core.Runtime; +using Wacs.Core.WASIp1; +using Wacs.WASIp1.Types; +using fd = System.UInt32; +using ptr = System.UInt32; +using size = System.UInt32; + +namespace Wacs.WASIp1 +{ + public class Sock : IBindable + { + private readonly State _state; + + public Sock(State state) => _state = state; + + public void BindToRuntime(WasmRuntime runtime) + { + string module = "wasi_snapshot_preview1"; + runtime.BindHostFunction>((module, "sock_accept"), SockAccept); + runtime.BindHostFunction>((module, "sock_recv"), SockRecv); + runtime.BindHostFunction>((module, "sock_send"), SockSend); + runtime.BindHostFunction>((module, "sock_shutdown"), SockShutdown); + } + + public ErrNo SockAccept(ExecContext ctx, fd sock, + FdFlags flags, ptr ro_fd) + { + return ErrNo.NotSup; + } + + public ErrNo SockRecv(ExecContext ctx, fd sock, + ptr ri_data, size ri_datalen, RiFlags ri_flags, + ptr ro_data_len, ptr ro_flags) + { + return ErrNo.NotSup; + } + + public ErrNo SockSend(ExecContext ctx, fd sock, + ptr si_data, size si_data_len, SiFlags si_flags, + ptr ret_data_len) + { + return ErrNo.NotSup; + } + + public ErrNo SockShutdown(ExecContext ctx, fd sock, SdFlags how) + { + return ErrNo.NotSup; + } + + } +} \ No newline at end of file diff --git a/Wacs.WASIp1/State.cs b/Wacs.WASIp1/State.cs index 3c64938..f17e323 100644 --- a/Wacs.WASIp1/State.cs +++ b/Wacs.WASIp1/State.cs @@ -15,6 +15,8 @@ // */ using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Net.Sockets; using System.Threading; using Wacs.WASIp1.Types; @@ -41,5 +43,9 @@ public uint GetNextFd { public VirtualPathMapper PathMapper { get; set; } = new(); + + + public Dictionary socketTable = new Dictionary(); + public int nextSocketDescriptor = 1; } } \ No newline at end of file diff --git a/Wacs.WASIp1/Types/RiFlags.cs b/Wacs.WASIp1/Types/RiFlags.cs new file mode 100644 index 0000000..7ff463f --- /dev/null +++ b/Wacs.WASIp1/Types/RiFlags.cs @@ -0,0 +1,31 @@ +// /* +// * Copyright 2024 Kelvin Nishikawa +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +using System; +using Wacs.Core.Attributes; +using Wacs.Core.Types; + +namespace Wacs.WASIp1.Types +{ + [Flags] + [WasmType(nameof(ValType.I32))] + public enum RiFlags : ushort + { + None = 0b0000, + RecvPeek = 0b0001, + RecvWaitAll = 0b0010, + } +} \ No newline at end of file diff --git a/Wacs.WASIp1/Types/RoFlags.cs b/Wacs.WASIp1/Types/RoFlags.cs new file mode 100644 index 0000000..288306d --- /dev/null +++ b/Wacs.WASIp1/Types/RoFlags.cs @@ -0,0 +1,30 @@ +// /* +// * Copyright 2024 Kelvin Nishikawa +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +using System; +using Wacs.Core.Attributes; +using Wacs.Core.Types; + +namespace Wacs.WASIp1.Types +{ + [Flags] + [WasmType(nameof(ValType.I32))] + public enum RoFlags : ushort + { + None = 0b0000, + RecvDataTruncated = 0b0001, + } +} \ No newline at end of file diff --git a/Wacs.WASIp1/Types/SdFlags.cs b/Wacs.WASIp1/Types/SdFlags.cs new file mode 100644 index 0000000..24bb6f4 --- /dev/null +++ b/Wacs.WASIp1/Types/SdFlags.cs @@ -0,0 +1,31 @@ +// /* +// * Copyright 2024 Kelvin Nishikawa +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +using System; +using Wacs.Core.Attributes; +using Wacs.Core.Types; + +namespace Wacs.WASIp1.Types +{ + [Flags] + [WasmType(nameof(ValType.I32))] + public enum SdFlags : ushort + { + None = 0b0000, + Rd = 0b0001, + Wr = 0b0010, + } +} \ No newline at end of file diff --git a/Wacs.WASIp1/Types/SiFlags.cs b/Wacs.WASIp1/Types/SiFlags.cs new file mode 100644 index 0000000..7f9c6b9 --- /dev/null +++ b/Wacs.WASIp1/Types/SiFlags.cs @@ -0,0 +1,29 @@ +// /* +// * Copyright 2024 Kelvin Nishikawa +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +using System; +using Wacs.Core.Attributes; +using Wacs.Core.Types; + +namespace Wacs.WASIp1.Types +{ + [Flags] + [WasmType(nameof(ValType.I32))] + public enum SiFlags : ushort + { + None = 0b0000, + } +} \ No newline at end of file diff --git a/Wacs.WASIp1/VirtualPathMapper.cs b/Wacs.WASIp1/VirtualPathMapper.cs index c519255..ca44f2e 100644 --- a/Wacs.WASIp1/VirtualPathMapper.cs +++ b/Wacs.WASIp1/VirtualPathMapper.cs @@ -93,6 +93,9 @@ public void MoveHostPath(string oldHostPath, string newHostPath) public string MapToHostPath(string guestPath) { + if (guestPath.Split(Path.DirectorySeparatorChar)[0] == "dev") + return guestPath; + if (string.IsNullOrWhiteSpace(guestPath)) throw new ArgumentException("Guest path cannot be empty", nameof(guestPath)); diff --git a/Wacs.WASIp1/Wasi.cs b/Wacs.WASIp1/Wasi.cs index d17784c..eda16b3 100644 --- a/Wacs.WASIp1/Wasi.cs +++ b/Wacs.WASIp1/Wasi.cs @@ -28,26 +28,30 @@ public class Wasi private readonly Proc _proc; private readonly Random _random; private readonly State _state; + private readonly Poll _poll; + private readonly Sock _sock; public Wasi(WasiConfiguration config) { _config = config; _state = new State(); - _proc = new Proc(_state); + _poll = new Poll(_state); _env = new Env(config); _clock = new Clock(config); _random = new Random(); - + _sock = new Sock(_state); _fs = new Filesystem(config, _state); } public void BindToRuntime(WasmRuntime runtime) { _proc.BindToRuntime(runtime); + _poll.BindToRuntime(runtime); _env.BindToRuntime(runtime); _clock.BindToRuntime(runtime); _random.BindToRuntime(runtime); + _sock.BindToRuntime(runtime); _fs.BindToRuntime(runtime); } } From 9de17b72a752ffb6034cf0237decc5a8ce00587f Mon Sep 17 00:00:00 2001 From: Kelvin Nishikawa Date: Tue, 26 Nov 2024 13:18:59 -0800 Subject: [PATCH 2/2] WASIp1-v0.9.3 --- Wacs.WASIp1/Wacs.WASIp1.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Wacs.WASIp1/Wacs.WASIp1.csproj b/Wacs.WASIp1/Wacs.WASIp1.csproj index 0c0f14d..9515136 100644 --- a/Wacs.WASIp1/Wacs.WASIp1.csproj +++ b/Wacs.WASIp1/Wacs.WASIp1.csproj @@ -12,9 +12,9 @@ https://github.com/kelnishi/WACS Apache-2.0 Wacs.WASIp1 - 0.9.2 + 0.9.3 true - 0.9.2 + 0.9.3 git netstandard2.1;net8.0