Fix process.spawn yielding issue

This commit is contained in:
Filip Tibell 2023-01-23 13:18:48 -05:00
parent 5839a7b021
commit c2ee188ad5
No known key found for this signature in database
2 changed files with 33 additions and 15 deletions

View file

@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
### Fixed
- Potential fix for spawned processes that yield erroring
with "attempt to yield across metamethod/c-call boundary"
## `0.0.5` - January 22nd, 2023
### Added

View file

@ -1,11 +1,12 @@
use std::{
env,
process::{exit, Stdio},
sync::Weak,
};
use mlua::prelude::*;
use os_str_bytes::RawOsString;
use smol::process::Command;
use smol::{process::Command, LocalExecutor};
use crate::utils::table_builder::TableBuilder;
@ -116,20 +117,30 @@ async fn process_spawn(
lua: &Lua,
(program, args): (String, Option<Vec<String>>),
) -> LuaResult<LuaTable> {
// Create and spawn a child process, and
// wait for it to terminate with output
let mut cmd = Command::new(program);
if let Some(args) = args {
cmd.args(args);
}
let child = cmd
.current_dir(env::current_dir().map_err(LuaError::external)?)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(LuaError::external)?;
let output = child.output().await.map_err(LuaError::external)?;
let exec = lua
.app_data_ref::<Weak<LocalExecutor>>()
.unwrap()
.upgrade()
.unwrap();
// Create and spawn a child process in a new task to prevent
// issues with yielding across the metamethod/c-call boundary
let output = exec
.spawn(async move {
let mut cmd = Command::new(program);
if let Some(args) = args {
cmd.args(args);
}
let child = cmd
.current_dir(env::current_dir().map_err(LuaError::external)?)
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(LuaError::external)?;
let output = child.output().await.map_err(LuaError::external)?;
Ok::<_, LuaError>(output)
})
.await?;
// NOTE: If an exit code was not given by the child process,
// we default to 1 if it yielded any error output, otherwise 0
let code = output