parent
640389bb2b
commit
a1363b5227
@ -57,9 +57,8 @@ pub const Builder = struct {
|
|||||||
%return zig_args.append(exe.name);
|
%return zig_args.append(exe.name);
|
||||||
|
|
||||||
printInvocation(self.zig_exe, zig_args);
|
printInvocation(self.zig_exe, zig_args);
|
||||||
const TODO_env: []const []const u8 = undefined; // TODO
|
var child = %return os.ChildProcess.spawn(self.zig_exe, zig_args.toSliceConst(), os.environ,
|
||||||
var child = %return os.ChildProcess.spawn(self.zig_exe, zig_args.toSliceConst(), TODO_env,
|
StdIo.Ignore, StdIo.Inherit, StdIo.Inherit, self.allocator);
|
||||||
StdIo.Ignore, StdIo.Inherit, StdIo.Inherit);
|
|
||||||
const term = %return child.wait();
|
const term = %return child.wait();
|
||||||
switch (term) {
|
switch (term) {
|
||||||
Term.Clean => |code| {
|
Term.Clean => |code| {
|
||||||
|
@ -83,7 +83,7 @@ pub coldcc fn abort() -> noreturn {
|
|||||||
c.abort();
|
c.abort();
|
||||||
}
|
}
|
||||||
switch (@compileVar("os")) {
|
switch (@compileVar("os")) {
|
||||||
Os.linux => {
|
Os.linux, Os.darwin, Os.macosx, Os.ios => {
|
||||||
_ = posix.raise(posix.SIGABRT);
|
_ = posix.raise(posix.SIGABRT);
|
||||||
_ = posix.raise(posix.SIGKILL);
|
_ = posix.raise(posix.SIGKILL);
|
||||||
while (true) {}
|
while (true) {}
|
||||||
@ -234,12 +234,12 @@ pub const ChildProcess = struct {
|
|||||||
Close,
|
Close,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn spawn(exe_path: []const u8, args: []const []const u8, env: []const []const u8,
|
pub fn spawn(exe_path: []const u8, args: []const []const u8, env: []const EnvPair,
|
||||||
stdin: StdIo, stdout: StdIo, stderr: StdIo) -> %ChildProcess
|
stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess
|
||||||
{
|
{
|
||||||
switch (@compileVar("os")) {
|
switch (@compileVar("os")) {
|
||||||
Os.linux, Os.macosx, Os.ios, Os.darwin => {
|
Os.linux, Os.macosx, Os.ios, Os.darwin => {
|
||||||
return spawnPosix(exe_path, args, env, stdin, stdout, stderr);
|
return spawnPosix(exe_path, args, env, stdin, stdout, stderr, allocator);
|
||||||
},
|
},
|
||||||
else => @compileError("Unsupported OS"),
|
else => @compileError("Unsupported OS"),
|
||||||
}
|
}
|
||||||
@ -301,8 +301,8 @@ pub const ChildProcess = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawnPosix(exe_path: []const u8, args: []const []const u8, env: []const []const u8,
|
fn spawnPosix(exe_path: []const u8, args: []const []const u8, env: []const EnvPair,
|
||||||
stdin: StdIo, stdout: StdIo, stderr: StdIo) -> %ChildProcess
|
stdin: StdIo, stdout: StdIo, stderr: StdIo, allocator: &Allocator) -> %ChildProcess
|
||||||
{
|
{
|
||||||
// TODO issue #295
|
// TODO issue #295
|
||||||
//const stdin_pipe = if (stdin == StdIo.Pipe) %return makePipe() else undefined;
|
//const stdin_pipe = if (stdin == StdIo.Pipe) %return makePipe() else undefined;
|
||||||
@ -358,7 +358,7 @@ pub const ChildProcess = struct {
|
|||||||
setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %%
|
setUpChildIo(stderr, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %%
|
||||||
|err| forkChildErrReport(err_pipe[1], err);
|
|err| forkChildErrReport(err_pipe[1], err);
|
||||||
|
|
||||||
const err = posix.getErrno(posix.execve(exe_path, args, env));
|
const err = posix.getErrno(%return execve(exe_path, args, env, allocator));
|
||||||
assert(err > 0);
|
assert(err > 0);
|
||||||
forkChildErrReport(err_pipe[1], switch (err) {
|
forkChildErrReport(err_pipe[1], switch (err) {
|
||||||
errno.EFAULT => unreachable,
|
errno.EFAULT => unreachable,
|
||||||
@ -419,6 +419,65 @@ pub const ChildProcess = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// This function must allocate memory to add a null terminating bytes on path and each arg.
|
||||||
|
/// It must also convert to KEY=VALUE\0 format for environment variables, and include null
|
||||||
|
/// pointers after the args and after the environment variables.
|
||||||
|
/// Also make the first arg equal to path.
|
||||||
|
fn execve(path: []const u8, argv: []const []const u8, envp: []const EnvPair, allocator: &Allocator) -> %usize {
|
||||||
|
const path_buf = %return allocator.alloc(u8, path.len + 1);
|
||||||
|
defer allocator.free(path_buf);
|
||||||
|
@memcpy(&path_buf[0], &path[0], path.len);
|
||||||
|
path_buf[path.len] = 0;
|
||||||
|
|
||||||
|
const argv_buf = %return allocator.alloc(?&const u8, argv.len + 2);
|
||||||
|
mem.set(?&const u8, argv_buf, null);
|
||||||
|
defer {
|
||||||
|
for (argv_buf) |arg, i| {
|
||||||
|
const arg_buf = if (const ptr ?= arg) ptr[0...argv[i].len + 1] else break;
|
||||||
|
allocator.free(arg_buf);
|
||||||
|
}
|
||||||
|
allocator.free(argv_buf);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Add path to the first argument.
|
||||||
|
const arg_buf = %return allocator.alloc(u8, path.len + 1);
|
||||||
|
@memcpy(&arg_buf[0], path.ptr, path.len);
|
||||||
|
arg_buf[path.len] = 0;
|
||||||
|
|
||||||
|
argv_buf[0] = arg_buf.ptr;
|
||||||
|
}
|
||||||
|
for (argv) |arg, i| {
|
||||||
|
const arg_buf = %return allocator.alloc(u8, arg.len + 1);
|
||||||
|
@memcpy(&arg_buf[0], arg.ptr, arg.len);
|
||||||
|
arg_buf[arg.len] = 0;
|
||||||
|
|
||||||
|
argv_buf[i + 1] = arg_buf.ptr;
|
||||||
|
}
|
||||||
|
argv_buf[argv.len + 1] = null;
|
||||||
|
|
||||||
|
const envp_buf = %return allocator.alloc(?&const u8, envp.len + 1);
|
||||||
|
mem.set(?&const u8, envp_buf, null);
|
||||||
|
defer {
|
||||||
|
for (envp_buf) |env, i| {
|
||||||
|
const env_buf = if (const ptr ?= env) ptr[0...envp[i].key.len + envp[i].value.len + 2] else break;
|
||||||
|
allocator.free(env_buf);
|
||||||
|
}
|
||||||
|
allocator.free(envp_buf);
|
||||||
|
}
|
||||||
|
for (envp) |pair, i| {
|
||||||
|
const env_buf = %return allocator.alloc(u8, pair.key.len + pair.value.len + 2);
|
||||||
|
@memcpy(&env_buf[0], pair.key.ptr, pair.key.len);
|
||||||
|
env_buf[pair.key.len] = '=';
|
||||||
|
@memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len);
|
||||||
|
env_buf[env_buf.len - 1] = 0;
|
||||||
|
|
||||||
|
envp_buf[i] = env_buf.ptr;
|
||||||
|
}
|
||||||
|
envp_buf[envp.len] = null;
|
||||||
|
|
||||||
|
return posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
pub const EnvPair = struct {
|
pub const EnvPair = struct {
|
||||||
key: []const u8,
|
key: []const u8,
|
||||||
value: []const u8,
|
value: []const u8,
|
||||||
|
@ -261,40 +261,8 @@ pub fn dup2(old: i32, new: i32) -> usize {
|
|||||||
arch.syscall2(arch.SYS_dup2, usize(old), usize(new))
|
arch.syscall2(arch.SYS_dup2, usize(old), usize(new))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execve_c(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize {
|
pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize {
|
||||||
arch.syscall3(arch.SYS_execve, path, argv, envp)
|
arch.syscall3(arch.SYS_execve, usize(path), usize(argv), usize(envp))
|
||||||
}
|
|
||||||
|
|
||||||
/// This function must allocate memory to add a null terminating bytes on path, each arg,
|
|
||||||
/// and each environment variable line, as well as a null pointer after the arg list and
|
|
||||||
/// environment variable list. We allocate stack memory since the process is about to get
|
|
||||||
/// wiped anyway.
|
|
||||||
pub fn execve(path: []const u8, argv: []const []const u8, envp: []const []const u8) -> usize {
|
|
||||||
const path_buf = @alloca(u8, path.len + 1);
|
|
||||||
@memcpy(&path_buf[0], &path[0], path.len);
|
|
||||||
path_buf[path.len] = 0;
|
|
||||||
|
|
||||||
const argv_buf = @alloca([]const ?&const u8, argv.len + 1);
|
|
||||||
for (argv) |arg, i| {
|
|
||||||
const arg_buf = @alloca(u8, arg.len + 1);
|
|
||||||
@memcpy(&arg_buf[0], &arg[0], arg.len);
|
|
||||||
arg_buf[arg.len] = 0;
|
|
||||||
|
|
||||||
argv[i] = arg_buf;
|
|
||||||
}
|
|
||||||
argv_buf[argv.len] = null;
|
|
||||||
|
|
||||||
const envp_buf = @alloca([]const ?&const u8, envp.len + 1);
|
|
||||||
for (envp) |env, i| {
|
|
||||||
const env_buf = @alloca(u8, env.len + 1);
|
|
||||||
@memcpy(&env_buf[0], &env[0], env.len);
|
|
||||||
env_buf[env.len] = 0;
|
|
||||||
|
|
||||||
envp[i] = env_buf;
|
|
||||||
}
|
|
||||||
envp_buf[envp.len] = null;
|
|
||||||
|
|
||||||
return execve_c(path_buf.ptr, argv_buf.ptr, envp_buf.ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fork() -> usize {
|
pub fn fork() -> usize {
|
||||||
|
@ -4,7 +4,13 @@ const io = std.io;
|
|||||||
const Builder = std.build.Builder;
|
const Builder = std.build.Builder;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
|
|
||||||
|
error InvalidArgs;
|
||||||
|
|
||||||
pub fn main(args: [][]u8) -> %void {
|
pub fn main(args: [][]u8) -> %void {
|
||||||
|
if (args.len < 2) {
|
||||||
|
%%io.stderr.printf("Expected first argument to be path to zig compiler\n");
|
||||||
|
return error.InvalidArgs;
|
||||||
|
}
|
||||||
const zig_exe = args[1];
|
const zig_exe = args[1];
|
||||||
const leftover_args = args[2...];
|
const leftover_args = args[2...];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user