package main import ( "fmt" "log" "os" "os/exec" "path/filepath" "runtime" ) // hostOpen launches the platform's "open" handler for target (a URL, file path, // or opaque string) without blocking. Errors after launch are logged, not // returned, since the GUI handler is fire-and-forget. // // It resolves the opener via realOpenerPath so a host that also shadows // `xdg-open`/`open` with this binary doesn't recurse back into client mode. func hostOpen(target string) error { name, args := openCommand(target) bin, err := realOpenerPath(name) if err != nil { return err } cmd := exec.Command(bin, args...) if err := cmd.Start(); err != nil { return fmt.Errorf("start %s: %w", bin, err) } go func() { if err := cmd.Wait(); err != nil { log.Printf("open %q exited: %v", target, err) } }() return nil } func openCommand(target string) (string, []string) { switch runtime.GOOS { case "darwin": return "open", []string{target} case "windows": return "rundll32", []string{"url.dll,FileProtocolHandler", target} default: return "xdg-open", []string{target} } } // defaultOpenerName is the platform's native opener, used as the fallback target // when we were invoked as `open-proxy open` rather than under a shadowed name. func defaultOpenerName() string { if runtime.GOOS == "darwin" { return "open" } return "xdg-open" } // localOpen runs the real opener (the next `name` on $PATH that isn't us) for // arg. Used as the client-side fallback when the host is unreachable. func localOpen(name, arg string) error { bin, err := realOpenerPath(name) if err != nil { return err } cmd := exec.Command(bin, arg) cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr return cmd.Run() } // realOpenerPath finds an executable named `name` on $PATH that is not this // binary (so a symlink shadowing `xdg-open`/`open` doesn't recurse into us). func realOpenerPath(name string) (string, error) { self := selfFileInfo() for _, dir := range filepath.SplitList(os.Getenv("PATH")) { if dir == "" { continue } cand := filepath.Join(dir, name) info, err := os.Stat(cand) // follows symlinks if err != nil || info.IsDir() || info.Mode()&0o111 == 0 { continue } // Compare by file identity (device+inode), not path string: a symlink or // hardlink pointing back at this binary is recognized as us regardless of // how its path is spelled or whether $PATH entries are relative. if self != nil && os.SameFile(self, info) { continue } return cand, nil } return "", fmt.Errorf("no real %q found on PATH", name) } func selfFileInfo() os.FileInfo { exe, err := os.Executable() if err != nil { return nil } info, err := os.Stat(exe) if err != nil { return nil } return info }