summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-08-17 13:37:55 -0500
committerJeff Carr <[email protected]>2025-08-17 22:55:02 -0500
commit6c099ef51399cfc81a25434e92f60a8d809503cd (patch)
treecb247368aeb9832970fd2e46dd4a0f540a4ca5f4
parente2783ce0699b0867209a8a024e7aa1f3d187b76f (diff)
work around GO plugin load failures not being cleaned up
-rw-r--r--argv.go15
-rw-r--r--init.go8
-rw-r--r--plugin.go5
-rw-r--r--pluginCheck.go62
4 files changed, 56 insertions, 34 deletions
diff --git a/argv.go b/argv.go
index fd34701..b94b2e6 100644
--- a/argv.go
+++ b/argv.go
@@ -11,12 +11,11 @@ This struct can be used with the go-arg package. These
are the generic default command line arguments for the 'GUI' package
*/
type ArgsGui struct {
- NoGui bool `arg:"--no-gui" help:"ignore all these gui problems"`
- GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui,stdin]"`
- GuiFile string `arg:"--gui-file" help:"Use a specific plugin.so file"`
- GuiTest string `arg:"--gui-test" help:"test a specific plugin.so will load"`
- GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
- GuiCheck string `arg:"--gui-check-plugin" help:"used to check if the plugin loads"`
+ NoGui bool `arg:"--no-gui" help:"ignore all these gui problems"`
+ GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui,stdin]"`
+ GuiFile string `arg:"--gui-file" help:"Use a specific plugin.so file"`
+ GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
+ GuiPluginHack string `arg:"--gui-check-plugin" help:"hack to verify GO plugins load"`
}
/*
@@ -34,9 +33,9 @@ func ArgToolkit() string {
func InitArg() {
arg.Register(&argGui)
- if argGui.GuiCheck != "" {
+ if argGui.GuiPluginHack != "" {
// does os.Exec() and does not return
- TestPluginAndExit()
+ testPluginAndExit()
}
}
diff --git a/init.go b/init.go
index 80d9d42..716aefb 100644
--- a/init.go
+++ b/init.go
@@ -280,9 +280,9 @@ func New() *Node {
// trapStdout()
}
*/
- if argGui.GuiTest != "" {
+ if argGui.GuiPluginHack != "" {
// does os.Exec() and does not return
- TestPluginAndExit()
+ testPluginAndExit()
}
initNew()
@@ -297,9 +297,9 @@ func NoGui() bool {
func (n *Node) Default() *Node {
var err error
// used to check if plugins load or not
- if argGui.GuiCheck != "" {
+ if argGui.GuiPluginHack != "" {
// does os.Exec() and does not return
- TestPluginAndExit()
+ testPluginAndExit()
os.Exit(0)
}
diff --git a/plugin.go b/plugin.go
index a599269..03f6e84 100644
--- a/plugin.go
+++ b/plugin.go
@@ -8,7 +8,6 @@ package gui
import (
"embed"
"errors"
- "fmt"
"os"
"path/filepath"
"plugin"
@@ -248,8 +247,8 @@ func initToolkit(name string, filename string) *aplug {
plug, err := plugin.Open(filename)
*/
- if err := CheckPluginViaSubprocess(filename); err != nil {
- fmt.Printf("initToolkit() subprocess load plugin failed: %v\n", err)
+ if err := checkPluginViaSubprocess(filename); err != nil {
+ log.Printf("initToolkit() subprocess load plugin failed: %v\n", err)
return nil
}
diff --git a/pluginCheck.go b/pluginCheck.go
index b7657f6..8e50ade 100644
--- a/pluginCheck.go
+++ b/pluginCheck.go
@@ -3,7 +3,6 @@ package gui
import (
"debug/buildinfo"
"errors"
- "fmt"
"os"
"os/exec"
"path/filepath"
@@ -13,9 +12,11 @@ import (
"go.wit.com/log"
)
-// CheckPluginCompatibility verifies that the plugin .so file was built
+// this doesn't work with GO111MODULE=off so it's mostly worthless
+// TODO: fix the GO binary so this works
+// verifies that the plugin .so file was built
// with the same Go version and dependency versions as the host binary.
-func CheckPluginCompatibility(pluginPath string) error {
+func checkPluginCompatibility(pluginPath string) error {
pluginInfo, err := buildinfo.ReadFile(pluginPath)
if err != nil {
return log.Errorf("failed to read plugin build info: %w", err)
@@ -55,66 +56,89 @@ func CheckPluginCompatibility(pluginPath string) error {
log.Printf("DEP HASH: version %s: plugin=%s, host=%s\n", dep.Path, dep.Version, hostVer)
}
+ log.Info("CHECK FINAL OK:", pluginPath)
return nil
}
// tests the plugin file will load
func testPluginOld() {
- _, err := plugin.Open(argGui.GuiTest)
+ _, err := plugin.Open(argGui.GuiPluginHack)
if err != nil {
- log.Log(PLUG, "plugin.Open() FAILED =", argGui.GuiTest, err)
+ log.Log(PLUG, "plugin.Open() FAILED =", argGui.GuiPluginHack, err)
os.Exit(-1)
}
- log.Log(PLUG, "plugin.Open() SUCCESS loading plugin =", argGui.GuiTest)
+ log.Log(PLUG, "plugin.Open() SUCCESS loading plugin =", argGui.GuiPluginHack)
os.Exit(0)
}
+func CheckPlugin() string {
+ if argGui.GuiPluginHack != "" {
+ // does os.Exec() and does not return
+ testPluginAndExit()
+ }
+ return "boo"
+}
+
// loads the plugin, then exits with 0 or -1
-func TestPluginAndExit() {
- log.Log(WARN, "TEST plugin START", argGui.GuiCheck)
+func testPluginAndExit() {
+ log.Log(WARN, "TEST plugin START", argGui.GuiPluginHack)
- absPath, err := filepath.Abs(argGui.GuiCheck)
+ absPath, err := filepath.Abs(argGui.GuiPluginHack)
if err != nil {
- log.Log(WARN, "TEST plugin FAILED", argGui.GuiCheck, absPath, err)
+ log.Log(WARN, "TEST plugin FAILED", argGui.GuiPluginHack, absPath, err)
os.Exit(-1)
}
- log.Log(WARN, "TEST plugin START abs:", absPath, argGui.GuiCheck)
+ log.Log(WARN, "TEST plugin START abs:", absPath, argGui.GuiPluginHack)
plug, err := checkPlug(absPath)
if plug == nil {
- log.Log(WARN, "TEST plugin failed (returned nil):", argGui.GuiCheck, absPath, err)
+ log.Log(WARN, "TEST plugin failed (returned nil):", argGui.GuiPluginHack, absPath, err)
+ log.Sleep(1)
os.Exit(-1)
}
if err == nil {
- log.Log(WARN, "TEST plugin probably worked", argGui.GuiCheck, absPath)
+ log.Log(WARN, "TEST plugin probably worked", argGui.GuiPluginHack, absPath)
+ log.Log(WARN, "os.Exit(0)")
os.Exit(0)
}
- log.Log(WARN, "TEST plugin failed", argGui.GuiCheck, absPath, err)
+ log.Log(WARN, "TEST plugin failed", argGui.GuiPluginHack, absPath, err)
+ log.Sleep(1)
os.Exit(-1)
}
-func CheckPluginViaSubprocess(path string) error {
+func checkPluginViaSubprocess(path string) error {
exe, err := os.Executable()
if err != nil {
- return fmt.Errorf("failed to get executable path: %w", err)
+ return log.Errorf("failed to get executable path: %w", err)
}
resolved, err := filepath.EvalSymlinks(exe)
if err != nil {
- return fmt.Errorf("failed to resolve executable symlink: %w", err)
+ return log.Errorf("failed to resolve executable symlink: %w", err)
}
- cmd := exec.Command(resolved, "--gui-check-plugin", path)
+ argv := []string{resolved, "--gui-check-plugin", path, "--no-port"}
+ log.Warn("RUNNING:", argv)
+ // cmd := exec.Command(resolved, "--gui-check-plugin", path, "--no-port")
+ cmd := exec.Command(argv[0], argv[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
+// retuns true if
+func IsGoPluginTestHack() bool {
+ if argGui.GuiPluginHack == "" {
+ return false
+ }
+ return true
+}
+
func checkPlug(pluginPath string) (*plugin.Plugin, error) {
// const pluginPath = "/tmp/gocui.so"
// ../../../toolkits/gocui/gocui.so
// /usr/lib/go-gui-toolkits/gocui.v0.22.46.so
- if err := CheckPluginCompatibility(pluginPath); err != nil {
+ if err := checkPluginCompatibility(pluginPath); err != nil {
log.Printf("Plugin check failed: %v\n", err)
return nil, err
}