Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,185 @@
|
||||
module os
|
||||
|
||||
fn C.setpgid(pid i32, pgid i32) i32
|
||||
|
||||
fn env_value_from_entries(env []string, name string) ?string {
|
||||
prefix := '${name}='
|
||||
for entry in env {
|
||||
if entry.starts_with(prefix) {
|
||||
return entry[prefix.len..]
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
fn (p &Process) unix_resolve_filename() !string {
|
||||
if is_abs_path(p.filename) {
|
||||
return p.filename
|
||||
}
|
||||
if p.filename.contains(path_separator) {
|
||||
if p.work_folder != '' {
|
||||
return abs_path(p.filename)
|
||||
}
|
||||
return p.filename
|
||||
}
|
||||
path := env_value_from_entries(p.env, 'PATH') or { return error_failed_to_find_executable() }
|
||||
return find_abs_path_of_executable_in_path_env(p.filename, path)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_spawn_process() int {
|
||||
mut pipeset := [6]int{}
|
||||
if p.use_stdio_ctl {
|
||||
mut dont_care := C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end
|
||||
dont_care = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end
|
||||
dont_care = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end
|
||||
_ = dont_care // using `_` directly on each above `pipe` fails to avoid C compiler generate an `-Wunused-result` warning
|
||||
}
|
||||
pid := fork()
|
||||
if pid != 0 {
|
||||
// This is the parent process after the fork.
|
||||
// Note: pid contains the process ID of the child process
|
||||
if p.use_stdio_ctl {
|
||||
p.stdio_fd[0] = pipeset[1] // store the write end of child's in
|
||||
p.stdio_fd[1] = pipeset[2] // store the read end of child's out
|
||||
p.stdio_fd[2] = pipeset[4] // store the read end of child's err
|
||||
// close the rest of the pipe fds, the parent does not need them
|
||||
fd_close(pipeset[0])
|
||||
fd_close(pipeset[3])
|
||||
fd_close(pipeset[5])
|
||||
}
|
||||
return pid
|
||||
}
|
||||
//
|
||||
// Here, we are in the child process.
|
||||
// It still shares file descriptors with the parent process,
|
||||
// but it is otherwise independent and can do stuff *without*
|
||||
// affecting the parent process.
|
||||
//
|
||||
if p.use_pgroup {
|
||||
C.setpgid(0, 0)
|
||||
}
|
||||
if p.use_stdio_ctl {
|
||||
// Redirect the child standard in/out/err to the pipes that
|
||||
// were created in the parent.
|
||||
// Close the parent's pipe fds, the child do not need them:
|
||||
fd_close(pipeset[1])
|
||||
fd_close(pipeset[2])
|
||||
fd_close(pipeset[4])
|
||||
// redirect the pipe fds to the child's in/out/err fds:
|
||||
C.dup2(pipeset[0], 0)
|
||||
C.dup2(pipeset[3], 1)
|
||||
C.dup2(pipeset[5], 2)
|
||||
// close the pipe fdsx after the redirection
|
||||
fd_close(pipeset[0])
|
||||
fd_close(pipeset[3])
|
||||
fd_close(pipeset[5])
|
||||
}
|
||||
p.filename = p.unix_resolve_filename() or {
|
||||
eprintln(err)
|
||||
exit(1)
|
||||
}
|
||||
if p.work_folder != '' {
|
||||
chdir(p.work_folder) or {}
|
||||
}
|
||||
execve(p.filename, p.args, p.env) or {
|
||||
eprintln(err)
|
||||
exit(1)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_stop_process() {
|
||||
C.kill(p.pid, C.SIGSTOP)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_resume_process() {
|
||||
C.kill(p.pid, C.SIGCONT)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_term_process() {
|
||||
C.kill(p.pid, C.SIGTERM)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_kill_process() {
|
||||
C.kill(p.pid, C.SIGKILL)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_kill_pgroup() {
|
||||
C.kill(-p.pid, C.SIGKILL)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_wait() {
|
||||
p.impl_check_pid_status(false, 0)
|
||||
}
|
||||
|
||||
fn (mut p Process) unix_is_alive() bool {
|
||||
return p.impl_check_pid_status(true, C.WNOHANG)
|
||||
}
|
||||
|
||||
fn (mut p Process) impl_check_pid_status(exit_early_on_ret0 bool, waitpid_options int) bool {
|
||||
mut cstatus := 0
|
||||
mut ret := -1
|
||||
$if !emscripten ? {
|
||||
ret = C.waitpid(p.pid, &cstatus, waitpid_options)
|
||||
}
|
||||
p.code = ret
|
||||
if ret == -1 {
|
||||
p.err = posix_get_error_msg(C.errno)
|
||||
return false
|
||||
}
|
||||
if exit_early_on_ret0 && ret == 0 {
|
||||
return true
|
||||
}
|
||||
mut pret, is_signaled := posix_wait4_to_exit_status(cstatus)
|
||||
if is_signaled {
|
||||
p.status = .aborted
|
||||
p.err = 'Terminated by signal ${pret:2d} (${sigint_to_signal_name(pret)})'
|
||||
pret += 128
|
||||
} else {
|
||||
p.status = .exited
|
||||
}
|
||||
p.code = pret
|
||||
return false
|
||||
}
|
||||
|
||||
// these are here to make v_win.c/v.c generation work in all cases:
|
||||
fn (mut p Process) win_spawn_process() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
fn (mut p Process) win_stop_process() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_resume_process() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_term_process() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_kill_process() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_kill_pgroup() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_wait() {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_is_alive() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
fn (mut p Process) win_write_string(_idx int, _s string) {
|
||||
}
|
||||
|
||||
fn (mut p Process) win_read_string(_idx int, _maxbytes int) (string, int) {
|
||||
return '', 0
|
||||
}
|
||||
|
||||
fn (mut p Process) win_is_pending(_idx int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
fn (mut p Process) win_slurp(_idx int) string {
|
||||
return ''
|
||||
}
|
||||
Reference in new issue
Block a user