Skip to content

Commit aee11f8

Browse files
author
Brian Sorahan
committed
add linux ServerPath, dynamically find scsynth executable
1 parent 6f6b8e5 commit aee11f8

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

server.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package sc
22

33
import (
4+
"errors"
45
"fmt"
6+
"os"
57
"os/exec"
68
"strconv"
9+
"strings"
710
"time"
811
)
912

1013
// DefaultServerPort is the default listening port for scsynth.
1114
const DefaultServerPort = 57120
1215

16+
// ErrNoScsynth happens when you try to start a SuperCollider
17+
// server but do not have an scsynth executable in your PATH.
18+
var ErrNoScsynth = errors.New("Please install scsynth somewhere in your PATH.")
19+
1320
// Server represents a running instance of scsynth.
1421
type Server struct {
1522
*exec.Cmd
@@ -19,6 +26,46 @@ type Server struct {
1926
StartTimeout time.Duration
2027
}
2128

29+
// getServerPath gets the path to the scsynth executable.
30+
func (s *Server) getServerPath() (string, error) {
31+
for _, file := range strings.Split(ServerPath, ":") {
32+
ok, err := isExecutable(file)
33+
if err != nil {
34+
return "", err
35+
}
36+
if ok {
37+
return file, nil
38+
}
39+
}
40+
41+
path, hasPath := os.LookupEnv("PATH")
42+
if !hasPath {
43+
return "", ErrNoScsynth
44+
}
45+
46+
for _, file := range strings.Split(path, ":") {
47+
ok, err := isExecutable(file)
48+
if err != nil {
49+
return "", err
50+
}
51+
if ok {
52+
return file, nil
53+
}
54+
}
55+
return "", ErrNoScsynth
56+
}
57+
58+
// isExecutable returns true if the provided file is executable, false otherwise.
59+
// It also returns any error that occurs while trying to read the file.
60+
func isExecutable(filename string) (bool, error) {
61+
info, err := os.Stat(filename)
62+
if err != nil {
63+
return false, err
64+
}
65+
mode := info.Mode()
66+
return ((mode & 0x01) | (mode & 0x08) | (mode & 0x40)) != 0, nil
67+
}
68+
2269
// args gets the command line args to scsynth
2370
func (s *Server) args() ([]string, error) {
2471
// Get the port.
@@ -48,7 +95,13 @@ func (s *Server) Start() error {
4895
if err != nil {
4996
return err
5097
}
51-
s.Cmd = exec.Command(ServerPath, args...)
98+
99+
serverPath, err := s.getServerPath()
100+
if err != nil {
101+
return err
102+
}
103+
104+
s.Cmd = exec.Command(serverPath, args...)
52105
if err := s.Cmd.Start(); err != nil {
53106
return err
54107
}

server_linux.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// +build linux
2+
package sc
3+
4+
// ServerPath is the path the scsynth executable on linux systems.
5+
const ServerPath = "/usr/bin/scsynth:/usr/local/bin/scsynth"

0 commit comments

Comments
 (0)