From a8ab27c48401549d868ceb33b3f7a8065066f271 Mon Sep 17 00:00:00 2001 From: Merritt Date: Sun, 11 Oct 2020 12:29:07 -0400 Subject: [PATCH] Fixed wine process bug Nyrna would sometimes fail to find the wine process. pgrep was not catching all .exe instances. (For example, does not find Dark Souls III). Replaced it with ps aux which does seem to catch them all. Additionally found a better way to pass shell commands with `bash -c`. --- helpers.go | 4 +++- suspend.go | 46 +++++++++++++++++++++++------------------- suspendlinux.go | 53 +++++++++++++++++++++++++++++++------------------ 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/helpers.go b/helpers.go index 2b05c938..b744717a 100644 --- a/helpers.go +++ b/helpers.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "log" ) @@ -8,6 +9,7 @@ import ( // simple errors cleaner and easier. func Check(e error) { if e != nil { - log.Println(e) + errorText := fmt.Sprintf("Caught an error: %v", e) + log.Println(errorText) } } diff --git a/suspend.go b/suspend.go index 4ba3f062..92de2a1a 100644 --- a/suspend.go +++ b/suspend.go @@ -54,27 +54,33 @@ func ToggleSuspend() { case err != nil: log.Println("No saved process details found") name, pid := findProcess() - process, err := process.NewProcess(pid) - Check(err) - status, err := process.Status() - Check(err) - if status == "T" { - status = "Suspended" + if pid == 0 { + log.Println("Error! Received PID 0.") + Notify("Error! Received PID 0.") } else { - status = "Running" - } - log.Println("Checking process - name:", name, "PID:", pid, "status:", status) - switch status { - case "Running": - log.Println("Suspending", name) - NotifySuspend(name) - process.Suspend() - case "Suspended": - log.Println("Resuming", name) - NotifyResume(name) - process.Resume() + process, err := process.NewProcess(pid) + Check(err) + status, err := process.Status() + Check(err) + if status == "T" { + status = "Suspended" + } else { + status = "Running" + } + log.Println("Checking process - name:", name, "PID:", pid, "status:", status) + switch status { + case "Running": + log.Println("Suspending", name) + NotifySuspend(name) + process.Suspend() + case "Suspended": + log.Println("Resuming", name) + NotifyResume(name) + process.Resume() + } + // Save suspended process details to file + SaveProcessFile(name, pid) } - // Save suspended process details to file - SaveProcessFile(name, pid) + } } diff --git a/suspendlinux.go b/suspendlinux.go index ccd60c88..f3193edc 100644 --- a/suspendlinux.go +++ b/suspendlinux.go @@ -53,45 +53,60 @@ func GetActiveWindowLinux() (string, int32) { } func findWineProcess() (string, int32) { - // Use pgrep to search for running *.exe processes + // Use ps to search for running *.exe processes log.Print("Searching for Wine process..") - pgrepOut, err := exec.Command("pgrep", ".exe$", "-l").Output() + cmd := "ps aux | grep .exe$" + psOutput, err := exec.Command("bash", "-c", cmd).Output() Check(err) - // Convert the pgrep output to a map - pgrepString := string(pgrepOut[:]) - pgrepSlice := strings.Fields(pgrepString) - pgrepMap := make(map[string]string) - for i := 0; i < len(pgrepSlice); i += 2 { - pgrepMap[pgrepSlice[i+1]] = pgrepSlice[i] + // Convert the output to a string so we can search and manipulate. + psString := string(psOutput[:]) + // Each line of the output is for a single process, so seperate them into + // a slice, one for each process found. + var rawProcesses []string = strings.Split(psString, "\n") + // Create a map of the found processes in the form of name:PID. + psMap := make(map[string]string) + for _, process := range rawProcesses { + if process != "" { + // Split the string by white space. + // 0th entry should be the user, which we don't care about. + // 1st entry should be the PID. + var parts []string = strings.Fields(process) + var PID string = parts[1] + // log.Printf("PID: %v", PID) + findName := strings.Split(process, "\\") + var processName string = findName[len(findName)-1] + // log.Printf("processName: %v", processName) + psMap[processName] = PID + } } // Print the results for debugging purposes - for name, pid := range pgrepMap { - log.Println("Name:", name, "=>", "PID:", pid) + for name, pid := range psMap { + log.Println("\n", "Name:", name, "\n", "PID:", pid, "\n ") } // Remove the .exe processes belonging to Wine - for name := range pgrepMap { + for name := range psMap { switch name { case "services.exe": - delete(pgrepMap, name) + delete(psMap, name) fallthrough case "explorer.exe": - delete(pgrepMap, name) + delete(psMap, name) fallthrough case "winedevice.exe": - delete(pgrepMap, name) + delete(psMap, name) fallthrough case "plugplay.exe": - delete(pgrepMap, name) + delete(psMap, name) } } - if len(pgrepMap) != 1 { - log.Println("Multiple remaining processes:", pgrepMap) - log.Fatal("Not able to find real wine process! Please report this issue.") + if len(psMap) != 1 { + log.Println("Multiple remaining processes:", psMap) + log.Println("Not able to find real wine process! Please report this issue.") } // Extract name and pid from the map var processName string var processIDint int - for name, pid := range pgrepMap { + for name, pid := range psMap { processName = name processIDint, err = strconv.Atoi(pid) Check(err)