2021-11-29 01:12:29 +00:00
|
|
|
package main
|
|
|
|
|
2021-11-29 21:12:52 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
2021-11-29 22:49:43 +00:00
|
|
|
"os/signal"
|
|
|
|
"strings"
|
|
|
|
"syscall"
|
2021-11-29 21:12:52 +00:00
|
|
|
)
|
|
|
|
|
2021-11-29 01:12:29 +00:00
|
|
|
func main() {
|
2021-11-29 21:12:52 +00:00
|
|
|
inittab := DefaultInitTab
|
2021-11-29 22:08:10 +00:00
|
|
|
if file, err := os.OpenFile("/etc/inittab", os.O_RDONLY, 0644); err == nil {
|
2021-11-29 21:12:52 +00:00
|
|
|
inittab = ParseInitTab(file)
|
|
|
|
err := file.Close()
|
|
|
|
if err != nil {
|
2021-11-29 22:08:39 +00:00
|
|
|
fmt.Printf("error closing inittab: %s\n", err)
|
2021-11-29 21:12:52 +00:00
|
|
|
}
|
2021-11-29 22:08:39 +00:00
|
|
|
} else {
|
|
|
|
fmt.Printf("error reading inittab: %s\n", err)
|
2021-11-29 21:12:52 +00:00
|
|
|
}
|
|
|
|
|
2021-11-29 22:49:43 +00:00
|
|
|
inittab.Entries(SysInit).ExecAll()
|
|
|
|
inittab.Entries(Wait).ExecAll()
|
|
|
|
inittab.Entries(Once).SpawnAll()
|
|
|
|
inittab.Entries(Respawn).RespawnAll()
|
|
|
|
|
|
|
|
// TODO implement AskFirst handling
|
|
|
|
|
|
|
|
sigs := make(chan os.Signal, 1)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
sig := <-sigs
|
|
|
|
switch sig {
|
|
|
|
case syscall.SIGUSR2:
|
|
|
|
// shutdown
|
|
|
|
inittab.Entries(Shutdown).ExecAll()
|
|
|
|
syscall.Reboot(syscall.LINUX_REBOOT_CMD_POWER_OFF)
|
|
|
|
|
|
|
|
case syscall.SIGTERM:
|
|
|
|
// reboot
|
|
|
|
inittab.Entries(Shutdown).ExecAll()
|
|
|
|
syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART)
|
|
|
|
|
|
|
|
case syscall.SIGQUIT:
|
|
|
|
inittab.Entries(Shutdown).ExecAll()
|
|
|
|
restart := inittab.Entries(Restart)[0]
|
|
|
|
cmdline := strings.Split(restart.Process, " ")
|
|
|
|
syscall.Exec(cmdline[0], cmdline[1:], []string{})
|
|
|
|
|
|
|
|
case syscall.SIGINT:
|
|
|
|
inittab.Entries(CtrlAltDel).ExecAll()
|
|
|
|
}
|
2021-11-29 22:08:39 +00:00
|
|
|
}
|
2021-11-29 22:49:43 +00:00
|
|
|
}()
|
2021-11-29 22:08:39 +00:00
|
|
|
|
2021-11-29 22:49:43 +00:00
|
|
|
signal.Notify(sigs, syscall.SIGUSR2, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
|
|
|
|
|
2021-11-29 23:59:53 +00:00
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
syscall.Wait4(-1, nil, 0, nil)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2021-11-29 22:49:43 +00:00
|
|
|
select {}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i InitTab) ExecAll() {
|
|
|
|
for _, entry := range i {
|
2021-11-29 22:08:39 +00:00
|
|
|
err := Exec(entry)
|
|
|
|
if err != nil {
|
2021-11-29 22:49:43 +00:00
|
|
|
fmt.Printf("error executing \"%s\": %s\n", entry.Process, err)
|
2021-11-29 22:08:39 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-29 22:49:43 +00:00
|
|
|
}
|
2021-11-29 22:08:39 +00:00
|
|
|
|
2021-11-29 22:49:43 +00:00
|
|
|
func (i InitTab) SpawnAll() {
|
|
|
|
for _, entry := range i {
|
2021-11-29 22:08:39 +00:00
|
|
|
_, err := Spawn(entry)
|
|
|
|
if err != nil {
|
2021-11-29 22:49:43 +00:00
|
|
|
fmt.Printf("error spawning \"%s\": %s\n", entry.Process, err)
|
2021-11-29 22:08:39 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-29 22:49:43 +00:00
|
|
|
}
|
2021-11-29 22:08:39 +00:00
|
|
|
|
2021-11-29 22:49:43 +00:00
|
|
|
func (i InitTab) RespawnAll() {
|
|
|
|
for _, entry := range i {
|
2021-11-29 22:08:39 +00:00
|
|
|
go func(entry InitTabEntry) {
|
|
|
|
for {
|
|
|
|
err := Exec(entry)
|
|
|
|
if err != nil {
|
2021-11-29 22:49:43 +00:00
|
|
|
fmt.Printf("error respawning \"%s\": %s\n", entry.Process, err)
|
2021-11-29 22:08:39 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}(entry)
|
|
|
|
}
|
2021-11-29 01:12:29 +00:00
|
|
|
}
|