Sample of Go code to "emulate" `fork` syscall: run a child process, returns new PID and exit parent (normally a shell).
```go
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
// Fork process as daemon, returns new process PID
func Fork() (int, error) {
cmd := exec.Command(os.Args[0], os.Args[1:]...)
// Add env to run process as daemon
cmd.Env = append(os.Environ(), "IS_DAEMON=1")
// Optional: redirect input/outputs
cmd.Stdin = nil
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
// Setsid is used to detach the process from the parent (normally a shell)
Setsid: true,
}
if err := cmd.Start(); err != nil {
return 0, err
}
return cmd.Process.Pid, nil
}
func runDaemon() {
for count := 1; count <= 5; count++ {
fmt.Printf("count=%d\n", count)
time.Sleep(1 * time.Second)
}
}
func main() {
if os.Getenv("IS_DAEMON") != "1" {
fmt.Printf("Start parent - pid = %d\n", os.Getpid())
pid, err := Fork()
if err != nil {
fmt.Printf("Unable to fork process")
os.Exit(1)
} else {
fmt.Printf("Start child - pid = %d\n", pid)
}
fmt.Printf("Parent exit - pid = %d\n", os.Getpid())
os.Exit(0)
}
runDaemon() // daemon logic here
fmt.Printf("Child exit - pid = %d\n", os.Getpid())
os.Exit(0)
}
```
Exec of this sample:
```sh
$ ./go-fork
Start parent - pid = 3093309
Start child - pid = 3093315
Parent exit - pid = 3093309
count=1
count=2
count=3
count=4
count=5
Child exit - pid = 3093315
```
Sample of Go code to "emulate" `fork` syscall: run a child process, returns new PID and exit parent (normally a shell).
```go
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
// Fork process as daemon, returns new process PID
func Fork() (int, error) {
cmd := exec.Command(os.Args[0], os.Args[1:]...)
// Add env to run process as daemon
cmd.Env = append(os.Environ(), "IS_DAEMON=1")
// Optional: redirect input/outputs
cmd.Stdin = nil
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
// Setsid is used to detach the process from the parent (normally a shell)
Setsid: true,
}
if err := cmd.Start(); err != nil {
return 0, err
}
return cmd.Process.Pid, nil
}
func runDaemon() {
for count := 1; count <= 5; count++ {
fmt.Printf("count=%d\n", count)
time.Sleep(1 * time.Second)
}
}
func main() {
if os.Getenv("IS_DAEMON") != "1" {
fmt.Printf("Start parent - pid = %d\n", os.Getpid())
pid, err := Fork()
if err != nil {
fmt.Printf("Unable to fork process")
os.Exit(1)
} else {
fmt.Printf("Start child - pid = %d\n", pid)
}
fmt.Printf("Parent exit - pid = %d\n", os.Getpid())
os.Exit(0)
}
runDaemon() // daemon logic here
fmt.Printf("Child exit - pid = %d\n", os.Getpid())
os.Exit(0)
}
```
Exec of this sample:
```sh
$ ./go-fork
Start parent - pid = 3093309
Start child - pid = 3093315
Parent exit - pid = 3093309
count=1
count=2
count=3
count=4
count=5
Child exit - pid = 3093315
```