{"id":14263218,"url":"https://github.com/WebAssembly/wasi-io","last_synced_at":"2025-08-13T09:32:41.645Z","repository":{"id":51645897,"uuid":"261895181","full_name":"WebAssembly/wasi-io","owner":"WebAssembly","description":"I/O Types proposal for WASI","archived":false,"fork":false,"pushed_at":"2024-12-05T14:39:05.000Z","size":119,"stargazers_count":146,"open_issues_count":13,"forks_count":21,"subscribers_count":25,"default_branch":"main","last_synced_at":"2024-12-05T15:30:40.514Z","etag":null,"topics":["proposals","wasi"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WebAssembly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-06T22:46:00.000Z","updated_at":"2024-12-05T14:37:36.000Z","dependencies_parsed_at":"2022-08-22T21:01:32.485Z","dependency_job_id":"fcf5c53b-a255-443c-91a2-84aae59eceba","html_url":"https://github.com/WebAssembly/wasi-io","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebAssembly%2Fwasi-io","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebAssembly%2Fwasi-io/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebAssembly%2Fwasi-io/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebAssembly%2Fwasi-io/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WebAssembly","download_url":"https://codeload.github.com/WebAssembly/wasi-io/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229754541,"owners_count":18119127,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["proposals","wasi"],"created_at":"2024-08-22T13:04:45.816Z","updated_at":"2024-12-14T20:30:41.780Z","avatar_url":"https://github.com/WebAssembly.png","language":null,"readme":"# WASI I/O\n\nA proposed [WebAssembly System Interface](https://github.com/WebAssembly/WASI) API.\n\n### Current Phase\n\nWASI I/O is currently in [Phase 3].\n\n[Phase 3]: https://github.com/WebAssembly/WASI/blob/main/Proposals.md#phase-3---implementation-phase-cg--wg\n\n### Champions\n\n- Dan Gohman\n\n### Portability Criteria\n\nWASI I/O must have host implementations which can pass the testsuite on at least Windows, macOS, and Linux.\n\nWASI I/O must have at least two complete independent implementations.\n\n## Table of Contents\n\n- [Introduction](#introduction)\n- [Goals [or Motivating Use Cases, or Scenarios]](#goals-or-motivating-use-cases-or-scenarios)\n- [Non-goals](#non-goals)\n- [API walk-through](#api-walk-through)\n  - [Use case: copying from input to output using `read`/`write`](#use-case-copying-from-input-to-output-using-readwrite)\n  - [Use case: copying from input to output using `splice`](#use-case-copying-from-input-to-output-using-splice)\n  - [Use case: copying from input to output using `forward`](#use-case-copying-from-input-to-output-using-forward)\n- [Detailed design discussion](#detailed-design-discussion)\n  - [Should we have support for non-blocking read/write?](#should-we-have-support-for-non-blocking-read-write)\n  - [Why do read/write use u64 sizes?[Tricky design choice 2]](#why-do-read-write-use-u64-sizes)\n  - [Why have a `forward` function when you can just `splice` in a loop?](#why-have-a-forward-function-when-you-can-just-splice-in-a-loop)\n- [Stakeholder Interest \u0026 Feedback](#stakeholder-interest--feedback)\n- [References \u0026 acknowledgements](#references--acknowledgements)\n\n### Introduction\n\nWasi I/O is an API providing I/O stream abstractions. There are two\ntypes, `input-stream`, and `output-stream`, which support `read` and\n`write`, respectively, as well as a number of utility functions.\n\n### Goals\n\n - Be usable by wasi-libc to implement POSIX-like file and socket APIs.\n - Support many different kinds of host streams, including files, sockets,\n   pipes, character devices, and more.\n\n### Non-goals\n\n - Support for async. That will be addressed in the component-model async\n   design, where we can have the benefit of tighter integration with language\n   bindings.\n - Bidirectional streams.\n\n### API walk-through\n\n#### Use Case: copying from input to output using `read`/`write`\n\n```rust\n   fn copy_data(input: InputStream, output: OutputStream) -\u003e Result\u003c(), StreamError\u003e {\n       const BUFFER_LEN: usize = 4096;\n\n       let wait_input = [subscribe_to_input_stream(input)];\n       let wait_output = [subscribe_to_output_stream(output)];\n\n       loop {\n           let (mut data, mut eos) = input.read(BUFFER_LEN)?;\n\n           // If we didn't get any data promptly, wait for it.\n           if data.len() == 0 {\n               let _ = poll_list(\u0026wait_input[..]);\n               (data, eos) = input.read(BUFFER_LEN)?;\n           }\n\n           let mut remaining = \u0026data[..];\n           while !remaining.is_empty() {\n               let mut num_written = output.write(remaining)?;\n\n               // If we didn't put any data promptly, wait for it.\n               if num_written == 0 {\n                   let _ = poll_list(\u0026wait_output[..]);\n                   num_written = output.write(remaining)?;\n               }\n\n               remaining = \u0026remaining[num_written..];\n           }\n           if eos {\n               break;\n           }\n       }\n       Ok(())\n   }\n```\n\n#### Use case: copying from input to output using `splice`\n\n```rust\n   fn copy_data(input: InputStream, output: OutputStream) -\u003e Result\u003c(), StreamError\u003e {\n       let wait_input = [subscribe_to_input_stream(input)];\n\n       loop {\n           let (num_copied, eos) = output.splice(input, u64::MAX)?;\n           if eos {\n               break;\n           }\n\n           // If we didn't get any data promptly, wait for it.\n           if num_copied == 0 {\n               let _ = poll_list(\u0026wait_input[..]);\n           }\n       }\n       Ok(())\n   }\n```\n\n#### Use case: copying from input to output using `forward`\n\n```rust\n   fn copy_data(input: InputStream, output: OutputStream) -\u003e Result\u003c(), StreamError\u003e {\n       output.forward(input)?;\n       Ok(())\n   }\n```\n\n### Detailed design discussion\n\n#### Should we have support for non-blocking read/write?\n\nThis may be something we'll need to revisit, but currently, the way\nnon-blocking streams work is that they perform reads or writes that\nread or write fewer bytes than requested.\n\n#### Why do read/write use u64 sizes?\n\nThis is to make the API independent of the address space size of\nthe caller. Callees are still advised to avoid using sizes that\nare larger than their instances will be able to allocate.\n\n#### Why have a `forward` function when you can just `splice` in a loop?\n\nThis seems like it'll be a common use case, and `forward`\naddresses it in a very simple way.\n\n### Stakeholder Interest \u0026 Feedback\n\nWasi-io is a dependency of wasi-filesystem, wasi-sockets, and wasi-http, and\nis a foundational piece of WASI Preview 2.\n\n### References \u0026 acknowledgements\n\nMany thanks for valuable feedback and advice from:\n\n- Thanks to Luke Wagner for many design functions and the design of\n  the component-model async streams which inform the design here.\n- Thanks to Calvin Prewitt for the idea to include a `forward` function\n  in this API.\n","funding_links":[],"categories":["others","Others","Components"],"sub_categories":["Interfaces"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWebAssembly%2Fwasi-io","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FWebAssembly%2Fwasi-io","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWebAssembly%2Fwasi-io/lists"}