New upstream version 0.0~git20191104.b3f3dc3
Shengjing Zhu
3 years ago
|
0 |
module github.com/mitchellh/panicwrap
|
|
1 |
|
|
2 |
go 1.13
|
19 | 19 |
"sync/atomic"
|
20 | 20 |
"syscall"
|
21 | 21 |
"time"
|
22 | |
|
23 | |
"github.com/kardianos/osext"
|
24 | 22 |
)
|
25 | 23 |
|
26 | 24 |
const (
|
|
117 | 115 |
}
|
118 | 116 |
|
119 | 117 |
// Get the path to our current executable
|
120 | |
exePath, err := osext.Executable()
|
|
118 |
exePath, err := os.Executable()
|
121 | 119 |
if err != nil {
|
122 | 120 |
return -1, err
|
123 | 121 |
}
|
|
228 | 226 |
// Wrapped checks if we're already wrapped according to the configuration
|
229 | 227 |
// given.
|
230 | 228 |
//
|
|
229 |
// It must be only called once with a non-nil configuration as it unsets
|
|
230 |
// the environment variable it uses to check if we are already wrapped.
|
|
231 |
// This prevents false positive if your program tries to execute itself
|
|
232 |
// recursively.
|
|
233 |
//
|
231 | 234 |
// Wrapped is very cheap and can be used early to short-circuit some pre-wrap
|
232 | 235 |
// logic your application may have.
|
233 | 236 |
//
|
|
252 | 255 |
// If the cookie key/value match our environment, then we are the
|
253 | 256 |
// child, so just exit now and tell the caller that we're the child
|
254 | 257 |
result := os.Getenv(c.CookieKey) == c.CookieValue
|
|
258 |
if result {
|
|
259 |
os.Unsetenv(c.CookieKey)
|
|
260 |
}
|
255 | 261 |
wrapCache.Store(result)
|
256 | 262 |
return result
|
257 | 263 |
}
|
161 | 161 |
|
162 | 162 |
if exitStatus < 0 {
|
163 | 163 |
if child {
|
164 | |
fmt.Printf("%v", Wrapped(config))
|
|
164 |
fmt.Printf("%v", Wrapped(nil))
|
165 | 165 |
}
|
166 | 166 |
os.Exit(0)
|
167 | 167 |
}
|
168 | 168 |
|
169 | 169 |
if !child {
|
|
170 |
fmt.Printf("%v", Wrapped(nil))
|
|
171 |
}
|
|
172 |
os.Exit(exitStatus)
|
|
173 |
case "recursive":
|
|
174 |
config := &WrapConfig{
|
|
175 |
Handler: panicHandler,
|
|
176 |
}
|
|
177 |
|
|
178 |
if len(args) > 0 && args[0] == "child" {
|
170 | 179 |
fmt.Printf("%v", Wrapped(config))
|
171 | |
}
|
172 | |
os.Exit(exitStatus)
|
|
180 |
os.Exit(0)
|
|
181 |
}
|
|
182 |
|
|
183 |
exitCode, err := Wrap(config)
|
|
184 |
if err != nil {
|
|
185 |
fmt.Fprintf(os.Stderr, "wrap error: %s", err)
|
|
186 |
os.Exit(1)
|
|
187 |
}
|
|
188 |
|
|
189 |
if Wrapped(nil) {
|
|
190 |
p := helperProcess("recursive", "child")
|
|
191 |
if err := p.Run(); err != nil {
|
|
192 |
fmt.Fprintf(os.Stderr, "wrap error: %s", err)
|
|
193 |
os.Exit(1)
|
|
194 |
}
|
|
195 |
os.Exit(0)
|
|
196 |
}
|
|
197 |
os.Exit(exitCode)
|
173 | 198 |
default:
|
174 | 199 |
fmt.Fprintf(os.Stderr, "Unknown command: %q\n", cmd)
|
175 | 200 |
os.Exit(2)
|
|
295 | 320 |
}
|
296 | 321 |
}
|
297 | 322 |
|
|
323 |
func TestPanicWrap_recursive(t *testing.T) {
|
|
324 |
stdout := new(bytes.Buffer)
|
|
325 |
|
|
326 |
p := helperProcess("recursive")
|
|
327 |
p.Stdout = stdout
|
|
328 |
if err := p.Run(); err != nil {
|
|
329 |
t.Fatalf("err: %s", err)
|
|
330 |
}
|
|
331 |
|
|
332 |
if !strings.Contains(stdout.String(), "false") {
|
|
333 |
t.Fatalf("Wrapped false positive: %#v", stdout.String())
|
|
334 |
}
|
|
335 |
}
|
|
336 |
|
298 | 337 |
func TestWrapped(t *testing.T) {
|
299 | 338 |
stdout := new(bytes.Buffer)
|
300 | 339 |
|