mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 00:01:16 +00:00
use fexecve on linux
This commit is contained in:
parent
b80b59125e
commit
0fd382e713
2 changed files with 45 additions and 17 deletions
|
@ -511,11 +511,12 @@ fn roc_run<'a, I: IntoIterator<Item = &'a OsStr>>(
|
||||||
) -> io::Result<i32> {
|
) -> io::Result<i32> {
|
||||||
match triple.architecture {
|
match triple.architecture {
|
||||||
Architecture::Wasm32 => {
|
Architecture::Wasm32 => {
|
||||||
let path = roc_run_executable_file_path(cwd, binary_bytes)?;
|
let executable = roc_run_executable_file_path(cwd, binary_bytes)?;
|
||||||
|
let path = executable.as_path();
|
||||||
// If possible, report the generated executable name relative to the current dir.
|
// If possible, report the generated executable name relative to the current dir.
|
||||||
let generated_filename = path
|
let generated_filename = path
|
||||||
.strip_prefix(env::current_dir().unwrap())
|
.strip_prefix(env::current_dir().unwrap())
|
||||||
.unwrap_or(&path);
|
.unwrap_or(path);
|
||||||
|
|
||||||
// No need to waste time freeing this memory,
|
// No need to waste time freeing this memory,
|
||||||
// since the process is about to exit anyway.
|
// since the process is about to exit anyway.
|
||||||
|
@ -561,7 +562,8 @@ fn roc_run_unix<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let path = roc_run_executable_file_path(cwd, binary_bytes)?;
|
let executable = roc_run_executable_file_path(cwd, binary_bytes)?;
|
||||||
|
let path = executable.as_path();
|
||||||
let path_cstring = CString::new(path.as_os_str().as_bytes()).unwrap();
|
let path_cstring = CString::new(path.as_os_str().as_bytes()).unwrap();
|
||||||
|
|
||||||
// argv is an array of pointers to strings passed to the new program
|
// argv is an array of pointers to strings passed to the new program
|
||||||
|
@ -589,22 +591,50 @@ fn roc_run_unix<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(
|
||||||
// program. The envp array must be terminated by a NULL pointer.
|
// program. The envp array must be terminated by a NULL pointer.
|
||||||
let envp = &[std::ptr::null()];
|
let envp = &[std::ptr::null()];
|
||||||
|
|
||||||
let execve_result =
|
match executable {
|
||||||
libc::execve(path_cstring.as_ptr().cast(), argv.as_ptr(), envp.as_ptr());
|
ExecutableFile::MemFd(fd, _) => {
|
||||||
|
if libc::fexecve(fd, argv.as_ptr(), envp.as_ptr()) != 0 {
|
||||||
if execve_result != 0 {
|
internal_error!(
|
||||||
internal_error!(
|
"libc::fexecve({:?}, ..., ...) failed: {:?}",
|
||||||
"libc::execve({:?}, ..., ...) failed: {:?}",
|
path,
|
||||||
path,
|
errno::errno()
|
||||||
errno::errno()
|
);
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
ExecutableFile::OnDisk(_) => {
|
||||||
|
if libc::execve(path_cstring.as_ptr().cast(), argv.as_ptr(), envp.as_ptr()) != 0 {
|
||||||
|
internal_error!(
|
||||||
|
"libc::execve({:?}, ..., ...) failed: {:?}",
|
||||||
|
path,
|
||||||
|
errno::errno()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(1)
|
Ok(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn roc_run_executable_file_path(cwd: &Path, binary_bytes: &mut [u8]) -> std::io::Result<PathBuf> {
|
#[derive(Debug, Clone)]
|
||||||
|
enum ExecutableFile {
|
||||||
|
MemFd(libc::c_int, PathBuf),
|
||||||
|
OnDisk(PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExecutableFile {
|
||||||
|
fn as_path(&self) -> &Path {
|
||||||
|
match self {
|
||||||
|
ExecutableFile::MemFd(_, path_buf) => path_buf.as_ref(),
|
||||||
|
ExecutableFile::OnDisk(path_buf) => path_buf.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn roc_run_executable_file_path(
|
||||||
|
cwd: &Path,
|
||||||
|
binary_bytes: &mut [u8],
|
||||||
|
) -> std::io::Result<ExecutableFile> {
|
||||||
if cfg!(target_os = "linux") {
|
if cfg!(target_os = "linux") {
|
||||||
// on linux, we use the `memfd_create` function to create an in-memory anonymous file.
|
// on linux, we use the `memfd_create` function to create an in-memory anonymous file.
|
||||||
let flags = 0;
|
let flags = 0;
|
||||||
|
@ -623,7 +653,7 @@ fn roc_run_executable_file_path(cwd: &Path, binary_bytes: &mut [u8]) -> std::io:
|
||||||
|
|
||||||
std::fs::write(&path, binary_bytes)?;
|
std::fs::write(&path, binary_bytes)?;
|
||||||
|
|
||||||
Ok(path)
|
Ok(ExecutableFile::MemFd(fd, path))
|
||||||
} else {
|
} else {
|
||||||
// we have not found a way yet to use a virtual file on MacOs. Hence we fall back to just
|
// we have not found a way yet to use a virtual file on MacOs. Hence we fall back to just
|
||||||
// writing the file to the file system, and using that file.
|
// writing the file to the file system, and using that file.
|
||||||
|
@ -631,7 +661,7 @@ fn roc_run_executable_file_path(cwd: &Path, binary_bytes: &mut [u8]) -> std::io:
|
||||||
|
|
||||||
std::fs::write(&app_path_buf, binary_bytes)?;
|
std::fs::write(&app_path_buf, binary_bytes)?;
|
||||||
|
|
||||||
Ok(app_path_buf)
|
Ok(ExecutableFile::OnDisk(app_path_buf))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,6 @@ const Unit = extern struct {};
|
||||||
pub fn main() u8 {
|
pub fn main() u8 {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = std.io.getStdErr().writer();
|
||||||
stdout.print("xkxkxkxkyay", .{}) catch unreachable;
|
|
||||||
// std.process.exit(0);
|
|
||||||
|
|
||||||
// start time
|
// start time
|
||||||
var ts1: std.os.timespec = undefined;
|
var ts1: std.os.timespec = undefined;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue