17
17
package halt
18
18
19
19
import (
20
+ "errors"
20
21
"fmt"
21
22
"os"
22
23
"syscall"
@@ -26,9 +27,9 @@ import (
26
27
"github.com/jessevdk/go-flags"
27
28
)
28
29
29
- const cmdName string = "halt"
30
+ var cmdName string = "halt"
30
31
31
- const version = "1.0.0 "
32
+ const version = "1.0.1 "
32
33
33
34
var osExit = os .Exit
34
35
@@ -38,29 +39,70 @@ const (
38
39
ExitFailuer
39
40
)
40
41
41
- type options struct {
42
+ type haltOpts struct {
42
43
Version bool `short:"v" long:"version" description:"Show halt command version"`
43
44
}
44
45
46
+ type poweroffOpts struct {
47
+ Version bool `short:"v" long:"version" description:"Show poweroff command version"`
48
+ }
49
+
50
+ type rebootOpts struct {
51
+ Version bool `short:"v" long:"version" description:"Show reboot command version"`
52
+ }
53
+
54
+ type allOptions struct {
55
+ halt haltOpts
56
+ po poweroffOpts
57
+ reboot rebootOpts
58
+ }
59
+
45
60
func Run () (int , error ) {
46
- var opts options
61
+ var allOpts allOptions = allOptions {}
62
+ var args []string
47
63
var err error
48
64
49
- if _ , err = parseArgs (& opts ); err != nil {
65
+ setCmdName (os .Args [0 ])
66
+ if args , err = parseArgs (& allOpts ); err != nil {
50
67
return ExitFailuer , nil
51
68
}
52
- return halt ()
69
+
70
+ switch cmdName {
71
+ case "halt" :
72
+ return halt (args , allOpts .halt )
73
+ case "poweroff" :
74
+ return poweroff (args , allOpts .po )
75
+ case "reboot" :
76
+ return reboot (args , allOpts .reboot )
77
+ }
78
+ return ExitFailuer , errors .New ("mimixbox failed to parse the argument (not halt, poweroff, reboot error)" )
53
79
}
54
80
55
- func halt () (int , error ) {
81
+ func halt (args [] string , opts haltOpts ) (int , error ) {
56
82
fmt .Fprintln (os .Stdout , "The system is going down NOW !!" )
57
- if err := killInitProcess (); err != nil {
83
+
84
+ recordWtmp ()
85
+ if err := powerOffSystem (); err != nil {
86
+ return ExitFailuer , err
87
+ }
88
+ return ExitSuccess , nil
89
+ }
90
+
91
+ func poweroff (args []string , opts poweroffOpts ) (int , error ) {
92
+ if err := powerOffSystem (); err != nil {
58
93
return ExitFailuer , err
59
94
}
60
95
return ExitSuccess , nil
61
96
}
62
97
63
- func killInitProcess () error {
98
+ func reboot (args []string , opts rebootOpts ) (int , error ) {
99
+ if err := rebootSystem (); err != nil {
100
+ return ExitFailuer , err
101
+ }
102
+ return ExitSuccess , nil
103
+ }
104
+
105
+ func powerOffSystem () error {
64
106
process , err := os .FindProcess (1 )
65
107
if err != nil {
66
108
return err
@@ -74,30 +116,51 @@ func killInitProcess() error {
74
116
// LINUX_REBOOT_CMD_HALT is semantically correct, but
75
117
// implementations vary (halt(8)), and most users will
76
118
// want power off.
77
- syscall .Reboot (0x4321fedc )
78
- return nil
119
+ return syscall .Reboot (syscall .LINUX_REBOOT_CMD_POWER_OFF )
120
+ }
121
+
122
+ func rebootSystem () error {
123
+ process , err := os .FindProcess (1 )
124
+ if err != nil {
125
+ return err
126
+ }
127
+ err = process .Signal (syscall .Signal (mb .ConvSignalNameToNum ("SIGUSR2" )))
128
+ if err != nil {
129
+ return err
130
+ }
131
+ syscall .Sync ()
132
+ return syscall .Reboot (syscall .LINUX_REBOOT_CMD_RESTART )
133
+ }
134
+
135
+ func recordWtmp () {
136
+ return // TODO:
137
+ }
138
+
139
+ func setCmdName (name string ) {
140
+ cmdName = name
79
141
}
80
142
81
- func parseArgs (opts * options ) ([]string , error ) {
143
+ func parseArgs (opts * allOptions ) ([]string , error ) {
82
144
p := initParser (opts )
83
145
84
146
args , err := p .Parse ()
85
147
if err != nil {
86
148
return nil , err
87
149
}
88
-
89
- if opts .Version {
90
- mb .ShowVersion (cmdName , version )
91
- osExit (ExitSuccess )
92
- }
93
-
150
+ showVersionAndExitIfNeeded (opts )
94
151
return args , nil
95
152
}
96
153
97
- func initParser (opts * options ) * flags.Parser {
154
+ func initParser (opts * allOptions ) * flags.Parser {
98
155
parser := flags .NewParser (opts , flags .Default )
99
156
parser .Name = cmdName
100
157
parser .Usage = "[OPTIONS]"
101
-
102
158
return parser
103
159
}
160
+
161
+ func showVersionAndExitIfNeeded (opts * allOptions ) {
162
+ if opts .halt .Version || opts .po .Version || opts .reboot .Version {
163
+ mb .ShowVersion (cmdName , version )
164
+ osExit (ExitSuccess )
165
+ }
166
+ }
0 commit comments