mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 20:13:40 +00:00
os: implement StartProcess
Signed-off-by: leongross <leon.gross@9elements.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build linux && !baremetal && !tinygo.wasm
|
||||
|
||||
package os
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// The only signal values guaranteed to be present in the os package on all
|
||||
// systems are os.Interrupt (send the process an interrupt) and os.Kill (force
|
||||
// the process to exit). On Windows, sending os.Interrupt to a process with
|
||||
// os.Process.Signal is not implemented; it will return an error instead of
|
||||
// sending a signal.
|
||||
var (
|
||||
Interrupt Signal = syscall.SIGINT
|
||||
Kill Signal = syscall.SIGKILL
|
||||
)
|
||||
|
||||
// Keep compatible with golang and always succeed and return new proc with pid on Linux.
|
||||
func findProcess(pid int) (*Process, error) {
|
||||
return &Process{Pid: pid}, nil
|
||||
}
|
||||
|
||||
func (p *Process) release() error {
|
||||
// NOOP for unix.
|
||||
p.Pid = -1
|
||||
// no need for a finalizer anymore
|
||||
runtime.SetFinalizer(p, nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
// This function is a wrapper around the forkExec function, which is a wrapper around the fork and execve system calls.
|
||||
// The StartProcess function creates a new process by forking the current process and then calling execve to replace the current process with the new process.
|
||||
// It thereby replaces the newly created process with the specified command and arguments.
|
||||
// Differences to upstream golang implementation (https://cs.opensource.google/go/go/+/master:src/syscall/exec_unix.go;l=143):
|
||||
// * No setting of Process Attributes
|
||||
// * Ignoring Ctty
|
||||
// * No ForkLocking (might be introduced by #4273)
|
||||
// * No parent-child communication via pipes (TODO)
|
||||
// * No waiting for crashes child processes to prohibit zombie process accumulation / Wait status checking (TODO)
|
||||
func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
|
||||
if argv == nil {
|
||||
return 0, errors.New("exec: no argv")
|
||||
}
|
||||
|
||||
if len(argv) == 0 {
|
||||
return 0, errors.New("exec: no argv")
|
||||
}
|
||||
|
||||
if attr == nil {
|
||||
attr = new(ProcAttr)
|
||||
}
|
||||
|
||||
p, err := fork()
|
||||
pid = int(p)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// else code runs in child, which then should exec the new process
|
||||
err = execve(argv0, argv, attr.Env)
|
||||
if err != nil {
|
||||
// exec failed
|
||||
return 0, err
|
||||
}
|
||||
// 3. TODO: use pipes to communicate back child status
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
// In Golang, the idiomatic way to create a new process is to use the StartProcess function.
|
||||
// Since the Model of operating system processes in tinygo differs from the one in Golang, we need to implement the StartProcess function differently.
|
||||
// The startProcess function is a wrapper around the forkExec function, which is a wrapper around the fork and execve system calls.
|
||||
// The StartProcess function creates a new process by forking the current process and then calling execve to replace the current process with the new process.
|
||||
// It thereby replaces the newly created process with the specified command and arguments.
|
||||
func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
|
||||
if attr != nil {
|
||||
if attr.Dir != "" {
|
||||
return nil, ErrNotImplementedDir
|
||||
}
|
||||
|
||||
if attr.Sys != nil {
|
||||
return nil, ErrNotImplementedSys
|
||||
}
|
||||
|
||||
if len(attr.Files) != 0 {
|
||||
return nil, ErrNotImplementedFiles
|
||||
}
|
||||
}
|
||||
|
||||
pid, err := forkExec(name, argv, attr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return findProcess(pid)
|
||||
}
|
||||
Reference in New Issue
Block a user