github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/libinit/proc_plan9.go (about) 1 // Copyright 2014-2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package libinit 6 7 import ( 8 "log" 9 "os" 10 "os/exec" 11 "syscall" 12 ) 13 14 // WaitOrphans waits for all remaining processes on the system to exit. 15 func WaitOrphans() uint { 16 var numReaped uint 17 for { 18 var w syscall.Waitmsg 19 err := syscall.Await(&w) 20 if err != nil { 21 break 22 } 23 log.Printf("Exited with %v", w) 24 numReaped++ 25 } 26 return numReaped 27 } 28 29 // WithRforkFlags adds rfork flags to the *exec.Cmd. 30 func WithRforkFlags(flags uintptr) CommandModifier { 31 return func(c *exec.Cmd) { 32 if c.SysProcAttr == nil { 33 c.SysProcAttr = &syscall.SysProcAttr{} 34 } 35 c.SysProcAttr.Rfork = int(flags) 36 } 37 } 38 39 func init() { 40 osDefault = plan9Default 41 } 42 43 func plan9Default(c *exec.Cmd) { 44 c.SysProcAttr = &syscall.SysProcAttr{} 45 } 46 47 // FIX ME: make it not linux-specific 48 // RunCommands runs commands in sequence. 49 // 50 // RunCommands returns how many commands existed and were attempted to run. 51 // 52 // commands must refer to absolute paths at the moment. 53 func RunCommands(debug func(string, ...interface{}), commands ...*exec.Cmd) int { 54 var cmdCount int 55 for _, cmd := range commands { 56 if _, err := os.Stat(cmd.Path); os.IsNotExist(err) { 57 debug("%v", err) 58 continue 59 } 60 61 cmdCount++ 62 debug("Trying to run %v", cmd) 63 if err := cmd.Start(); err != nil { 64 log.Printf("Error starting %v: %v", cmd, err) 65 continue 66 } 67 68 for { 69 var w syscall.Waitmsg 70 if err := syscall.Await(&w); err != nil { 71 debug("Error from Await: %v", err) 72 break 73 } 74 if w.Pid == cmd.Process.Pid { 75 debug("Shell exited, exit status %v", w) 76 break 77 } 78 debug("Reaped PID %d, exit status %v", w.Pid, w) 79 } 80 if err := cmd.Process.Release(); err != nil { 81 log.Printf("Error releasing process %v: %v", cmd, err) 82 } 83 } 84 return cmdCount 85 }