Skip to content

Commit dd4536e

Browse files
authored
Merge pull request #6058 from thaJeztah/restore_terminal
restore terminal when terminating after 3 signals
2 parents a09028c + a17b9c5 commit dd4536e

1 file changed

Lines changed: 18 additions & 4 deletions

File tree

cmd/docker/docker.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"io"
87
"os"
98
"os/exec"
109
"os/signal"
@@ -341,6 +340,9 @@ func tryPluginRun(ctx context.Context, dockerCli command.Cli, cmd *cobra.Command
341340
if force {
342341
_ = plugincmd.Process.Kill()
343342
_, _ = fmt.Fprint(dockerCli.Err(), "got 3 SIGTERM/SIGINTs, forcefully exiting\n")
343+
344+
// Restore terminal in case it was in raw mode.
345+
restoreTerminal(dockerCli)
344346
os.Exit(1)
345347
}
346348
}
@@ -388,7 +390,7 @@ func tryPluginRun(ctx context.Context, dockerCli command.Cli, cmd *cobra.Command
388390
// to be caught and the context to be marked as done, then registers a new
389391
// signal handler for subsequent signals. It forces the process to exit
390392
// after 3 SIGTERM/SIGINT signals.
391-
func forceExitAfter3TerminationSignals(ctx context.Context, w io.Writer) {
393+
func forceExitAfter3TerminationSignals(ctx context.Context, streams command.Streams) {
392394
// wait for the first signal to be caught and the context to be marked as done
393395
<-ctx.Done()
394396
// register a new signal handler for subsequent signals
@@ -399,10 +401,22 @@ func forceExitAfter3TerminationSignals(ctx context.Context, w io.Writer) {
399401
for i := 0; i < 2; i++ {
400402
<-sig
401403
}
402-
_, _ = fmt.Fprint(w, "\ngot 3 SIGTERM/SIGINTs, forcefully exiting\n")
404+
_, _ = fmt.Fprint(streams.Err(), "\ngot 3 SIGTERM/SIGINTs, forcefully exiting\n")
405+
406+
// Restore terminal in case it was in raw mode.
407+
restoreTerminal(streams)
403408
os.Exit(1)
404409
}
405410

411+
// restoreTerminal restores the terminal if it was in raw mode; this prevents
412+
// local echo from being disabled for the current terminal after forceful
413+
// termination. It's a no-op if there's no prior state to restore.
414+
func restoreTerminal(streams command.Streams) {
415+
streams.In().RestoreTerminal()
416+
streams.Out().RestoreTerminal()
417+
streams.Err().RestoreTerminal()
418+
}
419+
406420
//nolint:gocyclo
407421
func runDocker(ctx context.Context, dockerCli *command.DockerCli) error {
408422
tcmd := newDockerCommand(dockerCli)
@@ -468,7 +482,7 @@ func runDocker(ctx context.Context, dockerCli *command.DockerCli) error {
468482

469483
// This is a fallback for the case where the command does not exit
470484
// based on context cancellation.
471-
go forceExitAfter3TerminationSignals(ctx, dockerCli.Err())
485+
go forceExitAfter3TerminationSignals(ctx, dockerCli)
472486

473487
// We've parsed global args already, so reset args to those
474488
// which remain.

0 commit comments

Comments
 (0)