From 4995c511e581723ee9d441d500eda2e6d2e8a839 Mon Sep 17 00:00:00 2001
From: Matthew Heon <matthew.heon@pm.me>
Date: Wed, 1 Jul 2020 16:21:57 -0400
Subject: Fix `system service` panic from early hangup in events

We weren't actually halting the goroutine that sent events, so it
would continue sending even when the channel closed (the most
notable cause being early hangup - e.g. Control-c on a curl
session). Use a context to cancel the events goroutine and stop
sending events.

Fixes #6805

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
---
 libpod/events/logfile.go | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

(limited to 'libpod/events/logfile.go')

diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index 93e6fa3c9..28d0dc07e 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -1,6 +1,7 @@
 package events
 
 import (
+	"context"
 	"fmt"
 	"os"
 
@@ -40,7 +41,7 @@ func (e EventLogFile) Write(ee Event) error {
 }
 
 // Reads from the log file
-func (e EventLogFile) Read(options ReadOptions) error {
+func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error {
 	defer close(options.EventChannel)
 	eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until)
 	if err != nil {
@@ -50,6 +51,17 @@ func (e EventLogFile) Read(options ReadOptions) error {
 	if err != nil {
 		return err
 	}
+	funcDone := make(chan bool)
+	copy := true
+	go func() {
+		select {
+		case <-funcDone:
+			// Do nothing
+		case <-ctx.Done():
+			copy = false
+			t.Kill(errors.New("hangup by client"))
+		}
+	}()
 	for line := range t.Lines {
 		event, err := newEventFromJSONString(line.Text)
 		if err != nil {
@@ -65,10 +77,11 @@ func (e EventLogFile) Read(options ReadOptions) error {
 		for _, filter := range eventOptions {
 			include = include && filter(event)
 		}
-		if include {
+		if include && copy {
 			options.EventChannel <- event
 		}
 	}
+	funcDone <- true
 	return nil
 }
 
-- 
cgit v1.2.3-54-g00ecf