diff --git a/cmd/olcrtc/main.go b/cmd/olcrtc/main.go index 9a806c5..5890501 100644 --- a/cmd/olcrtc/main.go +++ b/cmd/olcrtc/main.go @@ -63,6 +63,7 @@ type failoverConfig struct { func main() { if err := run(); err != nil { logger.Error(err) + flushStderrFilter() os.Exit(1) } } diff --git a/cmd/olcrtc/stderr_filter_unix.go b/cmd/olcrtc/stderr_filter_unix.go index 613b28c..bc6c8b3 100644 --- a/cmd/olcrtc/stderr_filter_unix.go +++ b/cmd/olcrtc/stderr_filter_unix.go @@ -11,7 +11,12 @@ import ( "golang.org/x/sys/unix" ) -var stderrFilterOnce sync.Once //nolint:gochecknoglobals // process-wide stderr fd filter +var ( //nolint:gochecknoglobals // process-wide stderr fd filter + stderrFilterOnce sync.Once + stderrPipeWriter *os.File + stderrFilterDone chan struct{} + stderrFilterActive bool +) func installStderrFilter() { stderrFilterOnce.Do(func() { @@ -30,13 +35,29 @@ func installStderrFilter() { _ = unix.Close(origFD) return } - _ = writer.Close() + stderrPipeWriter = writer + stderrFilterDone = make(chan struct{}) + stderrFilterActive = true os.Stderr = os.NewFile(uintptr(unix.Stderr), "/dev/stderr") orig := os.NewFile(uintptr(origFD), "/dev/stderr-original") - go copyFilteredStderr(reader, orig) + go func() { + defer close(stderrFilterDone) + copyFilteredStderr(reader, orig) + }() }) } +// flushStderrFilter closes the pipe write ends so the filter goroutine +// sees EOF and drains any buffered output before the process exits. +func flushStderrFilter() { + if !stderrFilterActive { + return + } + _ = stderrPipeWriter.Close() + _ = unix.Close(unix.Stderr) + <-stderrFilterDone +} + func copyFilteredStderr(reader *os.File, out io.Writer) { defer func() { _ = reader.Close() }() br := bufio.NewReader(reader) diff --git a/cmd/olcrtc/stderr_filter_windows.go b/cmd/olcrtc/stderr_filter_windows.go index 760d7a8..c455367 100644 --- a/cmd/olcrtc/stderr_filter_windows.go +++ b/cmd/olcrtc/stderr_filter_windows.go @@ -3,3 +3,5 @@ package main func installStderrFilter() {} + +func flushStderrFilter() {}