aboutsummaryrefslogtreecommitdiffstats
path: root/lib/open.go
blob: c29ed0095e2c58c8a27c2e7645f6fc1c906c4b8d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package lib

import (
	"os/exec"
	"runtime"

	"git.sr.ht/~rjarry/aerc/logging"
)

var openBin string = "xdg-open"

func init() {
	if runtime.GOOS == "darwin" {
		openBin = "open"
	}
}

type xdgOpen struct {
	args  []string
	errCh chan (error)
	cmd   *exec.Cmd
}

// NewXDGOpen returns a handler for opening a file via the system handler xdg-open
// or comparable tools on other OSs than Linux
func NewXDGOpen(filename string) *xdgOpen {
	errch := make(chan error, 1)
	return &xdgOpen{
		errCh: errch,
		args:  []string{filename},
	}
}

// SetArgs sets additional arguments to the open command prior to the filename
func (xdg *xdgOpen) SetArgs(args []string) {
	args = append([]string{}, args...) // don't overwrite array of caller
	filename := xdg.args[len(xdg.args)-1]
	xdg.args = append(args, filename) //nolint:gocritic // intentional append to different slice
}

// Start the open handler.
// Returns an error if the command could not be started.
// Use Wait to wait for the commands completion and to check the error.
func (xdg *xdgOpen) Start() error {
	xdg.cmd = exec.Command(openBin, xdg.args...)
	err := xdg.cmd.Start()
	if err != nil {
		xdg.errCh <- err // for callers that just check the error from Wait()
		close(xdg.errCh)
		return err
	}
	go func() {
		defer logging.PanicHandler()

		xdg.errCh <- xdg.cmd.Wait()
		close(xdg.errCh)
	}()
	return nil
}

// Wait for the xdg-open command to complete
// The xdgOpen must have been started
func (xdg *xdgOpen) Wait() error {
	return <-xdg.errCh
}