os/exec: post-process lsof output on Android.
lsof is used to inspect the open file desciptors in exec_test.go.
In order to limit the output of lsof to the tested process, the tests use
lsof with the -p option, but the version of lsof in android seems to ignore
it. This change adds a post-processing step to filter out irrelevant entries.
Fixes golang/go#10206.
Change-Id: Ia789b8f5e1e9b95c7b55deac92d0d1fbf3ee74fb
Reviewed-on: https://go-review.googlesource.com/8025
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
index ebaef99..d3dec57 100644
--- a/src/os/exec/exec_test.go
+++ b/src/os/exec/exec_test.go
@@ -251,6 +251,12 @@
}
func numOpenFDS(t *testing.T) (n int, lsof []byte) {
+ if runtime.GOOS == "android" {
+ // Android's stock lsof does not obey the -p option,
+ // so extra filtering is needed. (golang.org/issue/10206)
+ return numOpenFDsAndroid(t)
+ }
+
lsof, err := exec.Command("lsof", "-b", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
if err != nil {
t.Skip("skipping test; error finding or running lsof")
@@ -258,6 +264,45 @@
return bytes.Count(lsof, []byte("\n")), lsof
}
+func numOpenFDsAndroid(t *testing.T) (n int, lsof []byte) {
+ raw, err := exec.Command("lsof").Output()
+ if err != nil {
+ t.Skip("skipping test; error finding or running lsof")
+ }
+
+ // First find the PID column index by parsing the first line, and
+ // select lines containing pid in the column.
+ pid := []byte(strconv.Itoa(os.Getpid()))
+ pidCol := -1
+
+ s := bufio.NewScanner(bytes.NewReader(raw))
+ for s.Scan() {
+ line := s.Bytes()
+ fields := bytes.Fields(line)
+ if pidCol < 0 {
+ for i, v := range fields {
+ if bytes.Equal(v, []byte("PID")) {
+ pidCol = i
+ break
+ }
+ }
+ lsof = append(lsof, line...)
+ continue
+ }
+ if bytes.Equal(fields[pidCol], pid) {
+ lsof = append(lsof, '\n')
+ lsof = append(lsof, line...)
+ }
+ }
+ if pidCol < 0 {
+ t.Fatal("error processing lsof output: unexpected header format")
+ }
+ if err := s.Err(); err != nil {
+ t.Fatalf("error processing lsof output: %v", err)
+ }
+ return bytes.Count(lsof, []byte("\n")), lsof
+}
+
var testedAlreadyLeaked = false
// basefds returns the number of expected file descriptors