github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/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 ( 19 w syscall.Waitmsg 20 ) 21 err := syscall.Await(&w) 22 if err != nil { 23 break 24 } 25 log.Printf("Exited with %v", w) 26 numReaped++ 27 } 28 return numReaped 29 } 30 31 // WithRforkFlags adds rfork flags to the *exec.Cmd. 32 func WithRforkFlags(flags uintptr) CommandModifier { 33 return func(c *exec.Cmd) { 34 if c.SysProcAttr == nil { 35 c.SysProcAttr = &syscall.SysProcAttr{} 36 } 37 c.SysProcAttr.Rfork = int(flags) 38 } 39 } 40 41 func init() { 42 osDefault = plan9Default 43 } 44 45 func plan9Default(c *exec.Cmd) { 46 c.SysProcAttr = &syscall.SysProcAttr{} 47 } 48 49 // FIX ME: make it not linux-specific 50 // RunCommands runs commands in sequence. 51 // 52 // RunCommands returns how many commands existed and were attempted to run. 53 // 54 // commands must refer to absolute paths at the moment. 55 func RunCommands(debug func(string, ...interface{}), commands ...*exec.Cmd) int { 56 var cmdCount int 57 for _, cmd := range commands { 58 if _, err := os.Stat(cmd.Path); os.IsNotExist(err) { 59 debug("%v", err) 60 continue 61 } 62 63 cmdCount++ 64 debug("Trying to run %v", cmd) 65 if err := cmd.Start(); err != nil { 66 log.Printf("Error starting %v: %v", cmd, err) 67 continue 68 } 69 70 for { 71 var w syscall.Waitmsg 72 if err := syscall.Await(&w); err != nil { 73 debug("Error from Await: %v", err) 74 break 75 } 76 if w.Pid == cmd.Process.Pid { 77 debug("Shell exited, exit status %v", w) 78 break 79 } 80 debug("Reaped PID %d, exit status %v", w.Pid, w) 81 } 82 if err := cmd.Process.Release(); err != nil { 83 log.Printf("Error releasing process %v: %v", cmd, err) 84 } 85 } 86 return cmdCount 87 }