From 37650afd9dd6bd93b31cda216ee18ae9a5b769d9 Mon Sep 17 00:00:00 2001 From: Jun Wu Date: Thu, 10 Nov 2022 21:58:38 -0800 Subject: [PATCH] Avoid running wasm-opt indefinitely POSIX says [1]: > If a file is removed from or added to the directory after the most recent > call to opendir() or rewinddir(), whether a subsequent call to readdir() > returns an entry for that file is unspecified. Writing `wasm-opt` output, renaming in a same directory being `readdir()`-ed is unspecified, and can cause the `readdir()` to loop indefinitely on certain filesystems. Fix it by collecting `readdir()` result first before making changes to the directory. [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html --- src/wasm_opt.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wasm_opt.rs b/src/wasm_opt.rs index d3ad4c66f..f9c377fe0 100644 --- a/src/wasm_opt.rs +++ b/src/wasm_opt.rs @@ -30,14 +30,17 @@ pub fn run( let wasm_opt_path = wasm_opt.binary(&Tool::WasmOpt.to_string())?; PBAR.info("Optimizing wasm binaries with `wasm-opt`..."); + let mut input_paths = Vec::new(); for file in out_dir.read_dir()? { let file = file?; let path = file.path(); if path.extension().and_then(|s| s.to_str()) != Some("wasm") { continue; } - - let tmp = path.with_extension("wasm-opt.wasm"); + input_paths.push(path); + } + for path in input_paths { + let tmp = path.with_extension("wasm-opt"); let mut cmd = Command::new(&wasm_opt_path); cmd.arg(&path).arg("-o").arg(&tmp).args(args); child::run(cmd, "wasm-opt")?;