From: Hyang-Ah (Hana) Kim Date: Tue, 24 Mar 2015 20:42:34 +0000 (-0400) Subject: os/exec: post-process lsof output on Android. X-Git-Tag: go1.5beta1~1437 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=41d58c3739e7a0e45542423519e0ebbdce27edda;p=gostls13.git 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 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go index ebaef992bc..d3dec57992 100644 --- a/src/os/exec/exec_test.go +++ b/src/os/exec/exec_test.go @@ -251,6 +251,12 @@ func TestPipeLookPathLeak(t *testing.T) { } 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 @@ func numOpenFDS(t *testing.T) (n int, lsof []byte) { 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