I need to use defer
to free allocations manually created using C
library, but I also need to os.Exit
with non 0 status at some point. The
After some research, refer to this this, I found an alternative that:
We can take advantage of panic
and recover
. It turns out that panic
, by nature, will honor defer
calls but will also always exit with non 0
status code and dump a stack trace. The trick is that we can override last aspect of panic behavior with:
package main
import "fmt"
import "os"
type Exit struct{ Code int }
// exit code handler
func handleExit() {
if e := recover(); e != nil {
if exit, ok := e.(Exit); ok == true {
os.Exit(exit.Code)
}
panic(e) // not an Exit, bubble up
}
}
Now, to exit a program at any point and still preserve any declared defer
instruction we just need to emit an Exit
type:
func main() {
defer handleExit() // plug the exit handler
defer fmt.Println("cleaning...")
panic(Exit{3}) // 3 is the exit code
}
It doesn't require any refactoring apart from plugging a line inside func main
:
func main() {
defer handleExit()
// ready to go
}
This scales pretty well with larger code bases so I'll leave it available for scrutinization. Hope it helps.
Playground: http://play.golang.org/p/4tyWwhcX0-