blob: 18348eab912aa0e440a5bb3c6cfd2e7bdc479fa4 [file] [log] [blame]
Shenghou Ma2fc67e72015-11-01 04:18:58 -05001// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Russ Coxd4b26382021-02-19 18:35:10 -05005//go:build linux || netbsd || (js && wasm)
Shenghou Ma2fc67e72015-11-01 04:18:58 -05006
7package os
8
9import (
10 "errors"
11 "runtime"
12)
13
Egon Elbrecfe5d792021-04-20 17:38:54 +030014func executable() (string, error) {
Shenghou Ma2fc67e72015-11-01 04:18:58 -050015 var procfn string
16 switch runtime.GOOS {
17 default:
18 return "", errors.New("Executable not implemented for " + runtime.GOOS)
David Crawshaw8a2c34e2016-11-28 17:23:12 -050019 case "linux", "android":
Shenghou Ma2fc67e72015-11-01 04:18:58 -050020 procfn = "/proc/self/exe"
21 case "netbsd":
22 procfn = "/proc/curproc/exe"
Shenghou Ma2fc67e72015-11-01 04:18:58 -050023 }
Egon Elbrecfe5d792021-04-20 17:38:54 +030024 path, err := Readlink(procfn)
Shenghou Ma2fc67e72015-11-01 04:18:58 -050025
Egon Elbrecfe5d792021-04-20 17:38:54 +030026 // When the executable has been deleted then Readlink returns a
27 // path appended with " (deleted)".
28 return stringsTrimSuffix(path, " (deleted)"), err
29}
30
31// stringsTrimSuffix is the same as strings.TrimSuffix.
32func stringsTrimSuffix(s, suffix string) string {
33 if len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix {
34 return s[:len(s)-len(suffix)]
35 }
36 return s
Shenghou Ma2fc67e72015-11-01 04:18:58 -050037}