From ce280e420ee46898275c25272dc37bdffd623394 Mon Sep 17 00:00:00 2001 From: Noboru Saito Date: Sun, 29 Sep 2024 21:02:43 +0900 Subject: [PATCH] Change to suspend with SIGSTOP Change suspend from subshell to SIGSTOP suspend. However, if Windows or OV_SUBSHELL is set, it will remain in subshell. Solve #630. --- oviewer/action.go | 36 +++++++++++++------ oviewer/action_test.go | 12 ------- oviewer/{sigtstp.go => suspend.go} | 9 +++++ ...{sigtstp_windows.go => suspend_windows.go} | 5 +++ 4 files changed, 40 insertions(+), 22 deletions(-) rename oviewer/{sigtstp.go => suspend.go} (59%) rename oviewer/{sigtstp_windows.go => suspend_windows.go} (73%) diff --git a/oviewer/action.go b/oviewer/action.go index 7faca849..dcffcc67 100644 --- a/oviewer/action.go +++ b/oviewer/action.go @@ -368,22 +368,38 @@ func specifyOnScreen(input string, max int) (int, error) { // It will return when you exit the shell. func (root *Root) suspend(context.Context) { log.Println("Suspend") - shell := os.Getenv("SHELL") - if err := root.shellSuspendResume(shell); err != nil { - root.setMessageLog(err.Error()) - } - log.Println("Resume") -} - -func (root *Root) shellSuspendResume(shell string) error { if err := root.Screen.Suspend(); err != nil { - return err + root.setMessageLog(err.Error()) + return } defer func() error { + log.Println("Resume") return root.Screen.Resume() }() - fmt.Println("suspended ov") + subshell := os.Getenv("OV_SUBSHELL") + // If the OS is something other than Windows + // or if the environment variable Subshell is not set, + // suspend with sigstop. + if runtime.GOOS != "windows" && subshell != "1" { + fmt.Println("suspended ov (use 'fg' to resume)") + if err := suspendProcess(); err != nil { + root.setMessageLog(err.Error()) + } + return + } + + // If the OS is Windows, + // or if the environment variable Subshell is set, + // start the subshell. + fmt.Println("suspended ov (use 'exit' to resume)") + shell := os.Getenv("SHELL") + if err := root.subShell(shell); err != nil { + root.setMessageLog(err.Error()) + } +} + +func (root *Root) subShell(shell string) error { if shell == "" { if runtime.GOOS == "windows" { shell = "CMD.EXE" diff --git a/oviewer/action_test.go b/oviewer/action_test.go index b10998c1..308cbd44 100644 --- a/oviewer/action_test.go +++ b/oviewer/action_test.go @@ -2,7 +2,6 @@ package oviewer import ( "context" - "os" "path/filepath" "reflect" "testing" @@ -1286,17 +1285,6 @@ func TestRoot_modeConfig(t *testing.T) { } } -func TestRoot_suspend(t *testing.T) { - root := rootHelper(t) - shell := os.Getenv("SHELL") - if got := root.shellSuspendResume(shell); got != nil { - t.Errorf("shellSuspendResume() = %v, want %v", got, nil) - } - if got := root.shellSuspendResume(""); got != nil { - t.Errorf("shellSuspendResume() = %v, want %v", got, nil) - } -} - func TestRoot_follow(t *testing.T) { tcellNewScreen = fakeScreen defer func() { diff --git a/oviewer/sigtstp.go b/oviewer/suspend.go similarity index 59% rename from oviewer/sigtstp.go rename to oviewer/suspend.go index 1a49d68b..e97fb514 100644 --- a/oviewer/sigtstp.go +++ b/oviewer/suspend.go @@ -15,3 +15,12 @@ func registerSIGTSTP() chan os.Signal { signal.Notify(sigSuspend, syscall.SIGTSTP) return sigSuspend } + +// suspendProcess sends SIGSTOP signal to itself. +func suspendProcess() error { + pid := syscall.Getpid() + if err := syscall.Kill(pid, syscall.SIGSTOP); err != nil { + return err + } + return nil +} diff --git a/oviewer/sigtstp_windows.go b/oviewer/suspend_windows.go similarity index 73% rename from oviewer/sigtstp_windows.go rename to oviewer/suspend_windows.go index db59d50c..cb74c4d7 100644 --- a/oviewer/sigtstp_windows.go +++ b/oviewer/suspend_windows.go @@ -12,3 +12,8 @@ func registerSIGTSTP() chan os.Signal { sigSuspend := make(chan os.Signal, 1) return sigSuspend } + +// suspendProcess is a dummy function. +func suspendProcess() error { + return nil +}