mirror of
https://github.com/caddyserver/caddy.git
synced 2024-11-22 10:01:11 +08:00
8eb2c37251
Modules that return an error during provisioning should still be cleaned up so that they don't leak any resources they may have allocated before the error occurred. Cleanup should be able to run even if Provision does not complete fully.
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package caddy
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
)
|
|
|
|
// TrapSignals create signal/interrupt handlers as best it can for the
|
|
// current OS. This is a rather invasive function to call in a Go program
|
|
// that captures signals already, so in that case it would be better to
|
|
// implement these handlers yourself.
|
|
func TrapSignals() {
|
|
trapSignalsCrossPlatform()
|
|
trapSignalsPosix()
|
|
}
|
|
|
|
// trapSignalsCrossPlatform captures SIGINT or interrupt (depending
|
|
// on the OS), which initiates a graceful shutdown. A second SIGINT
|
|
// or interrupt will forcefully exit the process immediately.
|
|
func trapSignalsCrossPlatform() {
|
|
go func() {
|
|
shutdown := make(chan os.Signal, 1)
|
|
signal.Notify(shutdown, os.Interrupt)
|
|
|
|
for i := 0; true; i++ {
|
|
<-shutdown
|
|
|
|
if i > 0 {
|
|
log.Println("[INFO] SIGINT: Force quit")
|
|
os.Exit(ExitCodeForceQuit)
|
|
}
|
|
|
|
log.Println("[INFO] SIGINT: Shutting down")
|
|
go gracefulStop("SIGINT")
|
|
}
|
|
}()
|
|
}
|
|
|
|
// gracefulStop exits the process as gracefully as possible.
|
|
func gracefulStop(sigName string) {
|
|
exitCode := ExitCodeSuccess
|
|
|
|
err := stopAndCleanup()
|
|
if err != nil {
|
|
log.Printf("[ERROR] %s stop: %v", sigName, err)
|
|
exitCode = ExitCodeFailedQuit
|
|
}
|
|
|
|
log.Printf("[INFO] %s: Shutdown done", sigName)
|
|
os.Exit(exitCode)
|
|
}
|
|
|
|
// Exit codes. Generally, you should NOT
|
|
// automatically restart the process if the
|
|
// exit code is ExitCodeFailedStartup (1).
|
|
const (
|
|
ExitCodeSuccess = iota
|
|
ExitCodeFailedStartup
|
|
ExitCodeForceQuit
|
|
ExitCodeFailedQuit
|
|
)
|