1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "tools/tools.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <errno.h>
20*795d594fSAndroid Build Coastguard Worker #include <stdlib.h>
21*795d594fSAndroid Build Coastguard Worker #include <unistd.h>
22*795d594fSAndroid Build Coastguard Worker
23*795d594fSAndroid Build Coastguard Worker #include <filesystem>
24*795d594fSAndroid Build Coastguard Worker
25*795d594fSAndroid Build Coastguard Worker #include "android-base/file.h"
26*795d594fSAndroid Build Coastguard Worker #include "android-base/result.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/common_art_test.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/globals.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/pidfd.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/time_utils.h"
31*795d594fSAndroid Build Coastguard Worker #include "gmock/gmock.h"
32*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
33*795d594fSAndroid Build Coastguard Worker #include "tools/testing.h"
34*795d594fSAndroid Build Coastguard Worker
35*795d594fSAndroid Build Coastguard Worker namespace art {
36*795d594fSAndroid Build Coastguard Worker namespace tools {
37*795d594fSAndroid Build Coastguard Worker namespace {
38*795d594fSAndroid Build Coastguard Worker
39*795d594fSAndroid Build Coastguard Worker using ::android::base::Result;
40*795d594fSAndroid Build Coastguard Worker using ::android::base::WriteStringToFile;
41*795d594fSAndroid Build Coastguard Worker using ::testing::UnorderedElementsAre;
42*795d594fSAndroid Build Coastguard Worker
CreateFile(const std::string & filename,const std::string & content="")43*795d594fSAndroid Build Coastguard Worker void CreateFile(const std::string& filename, const std::string& content = "") {
44*795d594fSAndroid Build Coastguard Worker std::filesystem::path path(filename);
45*795d594fSAndroid Build Coastguard Worker std::filesystem::create_directories(path.parent_path());
46*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(WriteStringToFile(content, filename));
47*795d594fSAndroid Build Coastguard Worker }
48*795d594fSAndroid Build Coastguard Worker
49*795d594fSAndroid Build Coastguard Worker class ArtToolsTest : public CommonArtTest {
50*795d594fSAndroid Build Coastguard Worker protected:
SetUp()51*795d594fSAndroid Build Coastguard Worker void SetUp() override {
52*795d594fSAndroid Build Coastguard Worker CommonArtTest::SetUp();
53*795d594fSAndroid Build Coastguard Worker scratch_dir_ = std::make_unique<ScratchDir>();
54*795d594fSAndroid Build Coastguard Worker scratch_path_ = scratch_dir_->GetPath();
55*795d594fSAndroid Build Coastguard Worker // Remove the trailing '/';
56*795d594fSAndroid Build Coastguard Worker scratch_path_.resize(scratch_path_.length() - 1);
57*795d594fSAndroid Build Coastguard Worker }
58*795d594fSAndroid Build Coastguard Worker
TearDown()59*795d594fSAndroid Build Coastguard Worker void TearDown() override {
60*795d594fSAndroid Build Coastguard Worker scratch_dir_.reset();
61*795d594fSAndroid Build Coastguard Worker CommonArtTest::TearDown();
62*795d594fSAndroid Build Coastguard Worker }
63*795d594fSAndroid Build Coastguard Worker
64*795d594fSAndroid Build Coastguard Worker std::unique_ptr<ScratchDir> scratch_dir_;
65*795d594fSAndroid Build Coastguard Worker std::string scratch_path_;
66*795d594fSAndroid Build Coastguard Worker };
67*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsTest,Glob)68*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsTest, Glob) {
69*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/def/000.txt");
70*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/def/ghi/123.txt");
71*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/def/ghi/456.txt");
72*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/def/ghi/456.pdf");
73*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/def/ghi/jkl/456.txt");
74*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/789.txt");
75*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/789.txt");
76*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/789.txt");
77*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/789.txt");
78*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/mno/123.txt");
79*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/mno/123.txt");
80*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/mno/123.txt");
81*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/mno/ccc/123.txt");
82*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/pqr/123.txt");
83*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/pqr/123.txt");
84*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/pqr/123.txt");
85*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/pqr/123.txt");
86*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/pqr/ccc/123.txt");
87*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/aaa/bbb/pqr/ccc/ddd/123.txt");
88*795d594fSAndroid Build Coastguard Worker
89*795d594fSAndroid Build Coastguard Worker // This symlink will cause infinite recursion. It should not be followed.
90*795d594fSAndroid Build Coastguard Worker std::filesystem::create_directory_symlink(scratch_path_ + "/abc/aaa/bbb/pqr",
91*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/pqr/lnk");
92*795d594fSAndroid Build Coastguard Worker
93*795d594fSAndroid Build Coastguard Worker // This is a directory. It should not be included in the results.
94*795d594fSAndroid Build Coastguard Worker std::filesystem::create_directory(scratch_path_ + "/abc/def/ghi/000.txt");
95*795d594fSAndroid Build Coastguard Worker
96*795d594fSAndroid Build Coastguard Worker std::vector<std::string> patterns = {
97*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/def/000.txt",
98*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/def/ghi/*.txt",
99*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/**/789.txt",
100*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/**/mno/*.txt",
101*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/**/pqr/**",
102*795d594fSAndroid Build Coastguard Worker };
103*795d594fSAndroid Build Coastguard Worker
104*795d594fSAndroid Build Coastguard Worker EXPECT_THAT(Glob(patterns, scratch_path_),
105*795d594fSAndroid Build Coastguard Worker UnorderedElementsAre(scratch_path_ + "/abc/def/000.txt",
106*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/def/ghi/123.txt",
107*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/def/ghi/456.txt",
108*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/789.txt",
109*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/789.txt",
110*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/789.txt",
111*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/mno/123.txt",
112*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/mno/123.txt",
113*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/mno/123.txt",
114*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/pqr/123.txt",
115*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/pqr/123.txt",
116*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/pqr/123.txt",
117*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/pqr/ccc/123.txt",
118*795d594fSAndroid Build Coastguard Worker scratch_path_ + "/abc/aaa/bbb/pqr/ccc/ddd/123.txt"));
119*795d594fSAndroid Build Coastguard Worker }
120*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsTest,EscapeGlob)121*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsTest, EscapeGlob) {
122*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/**");
123*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/*.txt");
124*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/?.txt");
125*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/[a-z].txt");
126*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/**.txt");
127*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/??.txt");
128*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/[a-z[a-z]][a-z].txt");
129*795d594fSAndroid Build Coastguard Worker
130*795d594fSAndroid Build Coastguard Worker // Paths that shouldn't be matched if the paths above are escaped.
131*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/abc/b.txt");
132*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/b.txt");
133*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/*b.txt");
134*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/?b.txt");
135*795d594fSAndroid Build Coastguard Worker CreateFile(scratch_path_ + "/[a-zb]b.txt");
136*795d594fSAndroid Build Coastguard Worker
137*795d594fSAndroid Build Coastguard Worker // Verifies that the escaped path only matches the given path.
138*795d594fSAndroid Build Coastguard Worker auto verify_escape = [this](const std::string& file) {
139*795d594fSAndroid Build Coastguard Worker EXPECT_THAT(Glob({EscapeGlob(file)}, scratch_path_), UnorderedElementsAre(file));
140*795d594fSAndroid Build Coastguard Worker };
141*795d594fSAndroid Build Coastguard Worker
142*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/**");
143*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/*.txt");
144*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/?.txt");
145*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/[a-z].txt");
146*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/**.txt");
147*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/**");
148*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/??.txt");
149*795d594fSAndroid Build Coastguard Worker verify_escape(scratch_path_ + "/[a-z[a-z]][a-z].txt");
150*795d594fSAndroid Build Coastguard Worker }
151*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsTest,PathStartsWith)152*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsTest, PathStartsWith) {
153*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a/b", "/a"));
154*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a/b", "/a/"));
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(PathStartsWith("/a/c", "/a/b"));
157*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(PathStartsWith("/ab", "/a"));
158*795d594fSAndroid Build Coastguard Worker
159*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a", "/a"));
160*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a/", "/a"));
161*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a", "/a/"));
162*795d594fSAndroid Build Coastguard Worker
163*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/a", "/"));
164*795d594fSAndroid Build Coastguard Worker EXPECT_TRUE(PathStartsWith("/", "/"));
165*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(PathStartsWith("/", "/a"));
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker
168*795d594fSAndroid Build Coastguard Worker class ArtToolsEnsureNoProcessInDirTest : public ArtToolsTest {
169*795d594fSAndroid Build Coastguard Worker protected:
SetUp()170*795d594fSAndroid Build Coastguard Worker void SetUp() override {
171*795d594fSAndroid Build Coastguard Worker ArtToolsTest::SetUp();
172*795d594fSAndroid Build Coastguard Worker
173*795d594fSAndroid Build Coastguard Worker if (!PidfdOpen(getpid(), /*flags=*/0).ok() && errno == ENOSYS) {
174*795d594fSAndroid Build Coastguard Worker GTEST_SKIP() << "'pidfd_open' is not available";
175*795d594fSAndroid Build Coastguard Worker }
176*795d594fSAndroid Build Coastguard Worker
177*795d594fSAndroid Build Coastguard Worker related_dir_ = scratch_path_ + "/related";
178*795d594fSAndroid Build Coastguard Worker unrelated_dir_ = scratch_path_ + "/unrelated";
179*795d594fSAndroid Build Coastguard Worker
180*795d594fSAndroid Build Coastguard Worker std::string sleep_bin = GetSleepBin();
181*795d594fSAndroid Build Coastguard Worker if (sleep_bin.empty()) {
182*795d594fSAndroid Build Coastguard Worker GTEST_SKIP() << "'sleep' is not available";
183*795d594fSAndroid Build Coastguard Worker }
184*795d594fSAndroid Build Coastguard Worker
185*795d594fSAndroid Build Coastguard Worker std::filesystem::create_directories(related_dir_);
186*795d594fSAndroid Build Coastguard Worker std::filesystem::create_directories(unrelated_dir_);
187*795d594fSAndroid Build Coastguard Worker std::filesystem::copy(sleep_bin, related_dir_ + "/sleep");
188*795d594fSAndroid Build Coastguard Worker std::filesystem::copy(sleep_bin, unrelated_dir_ + "/sleep");
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker
191*795d594fSAndroid Build Coastguard Worker std::string related_dir_;
192*795d594fSAndroid Build Coastguard Worker std::string unrelated_dir_;
193*795d594fSAndroid Build Coastguard Worker
194*795d594fSAndroid Build Coastguard Worker private:
GetSleepBin()195*795d594fSAndroid Build Coastguard Worker std::string GetSleepBin() {
196*795d594fSAndroid Build Coastguard Worker if constexpr (kIsTargetAndroid) {
197*795d594fSAndroid Build Coastguard Worker return GetBin("sleep");
198*795d594fSAndroid Build Coastguard Worker }
199*795d594fSAndroid Build Coastguard Worker if (access("/usr/bin/sleep", X_OK) == 0) {
200*795d594fSAndroid Build Coastguard Worker return "/usr/bin/sleep";
201*795d594fSAndroid Build Coastguard Worker }
202*795d594fSAndroid Build Coastguard Worker return "";
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker };
205*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsEnsureNoProcessInDirTest,WaitsProcesses)206*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsEnsureNoProcessInDirTest, WaitsProcesses) {
207*795d594fSAndroid Build Coastguard Worker std::vector<std::string> args_1{related_dir_ + "/sleep", "0.3"};
208*795d594fSAndroid Build Coastguard Worker auto [pid_1, scope_guard_1] = ScopedExec(args_1, /*wait=*/false);
209*795d594fSAndroid Build Coastguard Worker std::vector<std::string> args_2{unrelated_dir_ + "/sleep", "2"};
210*795d594fSAndroid Build Coastguard Worker auto [pid_2, scope_guard_2] = ScopedExec(args_2, /*wait=*/false);
211*795d594fSAndroid Build Coastguard Worker NanoSleep(100'000'000); // Wait for child processes to exec.
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker ASSERT_RESULT_OK(EnsureNoProcessInDir(related_dir_, /*timeout_ms=*/5000, /*try_kill=*/false));
214*795d594fSAndroid Build Coastguard Worker
215*795d594fSAndroid Build Coastguard Worker // Check the current status of the process with `WNOHANG`. The related process should have exited,
216*795d594fSAndroid Build Coastguard Worker // so `si_signo` should be `SIGCHLD`.
217*795d594fSAndroid Build Coastguard Worker siginfo_t info;
218*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(TEMP_FAILURE_RETRY(waitid(P_PID, pid_1, &info, WEXITED | WNOWAIT | WNOHANG)), 0);
219*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_signo, SIGCHLD);
220*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_code, CLD_EXITED);
221*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_status, 0);
222*795d594fSAndroid Build Coastguard Worker
223*795d594fSAndroid Build Coastguard Worker // The method should not wait on unrelated processes. The unrelated process should not have
224*795d594fSAndroid Build Coastguard Worker // exited, so `si_signo` should be 0.
225*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(TEMP_FAILURE_RETRY(waitid(P_PID, pid_2, &info, WEXITED | WNOWAIT | WNOHANG)), 0);
226*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_signo, 0);
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsEnsureNoProcessInDirTest,TimesOut)229*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsEnsureNoProcessInDirTest, TimesOut) {
230*795d594fSAndroid Build Coastguard Worker std::vector<std::string> args{related_dir_ + "/sleep", "5"};
231*795d594fSAndroid Build Coastguard Worker auto [pid, scope_guard] = ScopedExec(args, /*wait=*/false);
232*795d594fSAndroid Build Coastguard Worker NanoSleep(100'000'000); // Wait for child processes to exec.
233*795d594fSAndroid Build Coastguard Worker
234*795d594fSAndroid Build Coastguard Worker Result<void> result = EnsureNoProcessInDir(related_dir_, /*timeout_ms=*/200, /*try_kill=*/false);
235*795d594fSAndroid Build Coastguard Worker EXPECT_FALSE(result.ok());
236*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(result.error().message(), "Some process(es) are still running after 200ms");
237*795d594fSAndroid Build Coastguard Worker
238*795d594fSAndroid Build Coastguard Worker // The process should not have exited.
239*795d594fSAndroid Build Coastguard Worker siginfo_t info;
240*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED | WNOWAIT | WNOHANG)), 0);
241*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_signo, 0);
242*795d594fSAndroid Build Coastguard Worker }
243*795d594fSAndroid Build Coastguard Worker
TEST_F(ArtToolsEnsureNoProcessInDirTest,KillsProcesses)244*795d594fSAndroid Build Coastguard Worker TEST_F(ArtToolsEnsureNoProcessInDirTest, KillsProcesses) {
245*795d594fSAndroid Build Coastguard Worker std::vector<std::string> args_1{related_dir_ + "/sleep", "5"};
246*795d594fSAndroid Build Coastguard Worker auto [pid_1, scope_guard_1] = ScopedExec(args_1, /*wait=*/false);
247*795d594fSAndroid Build Coastguard Worker std::vector<std::string> args_2{unrelated_dir_ + "/sleep", "5"};
248*795d594fSAndroid Build Coastguard Worker auto [pid_2, scope_guard_2] = ScopedExec(args_2, /*wait=*/false);
249*795d594fSAndroid Build Coastguard Worker NanoSleep(100'000'000); // Wait for child processes to exec.
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker ASSERT_RESULT_OK(EnsureNoProcessInDir(related_dir_, /*timeout_ms=*/200, /*try_kill=*/true));
252*795d594fSAndroid Build Coastguard Worker
253*795d594fSAndroid Build Coastguard Worker // The related process should have been killed.
254*795d594fSAndroid Build Coastguard Worker siginfo_t info;
255*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(TEMP_FAILURE_RETRY(waitid(P_PID, pid_1, &info, WEXITED | WNOWAIT | WNOHANG)), 0);
256*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_signo, SIGCHLD);
257*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_code, CLD_KILLED);
258*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_status, SIGKILL);
259*795d594fSAndroid Build Coastguard Worker
260*795d594fSAndroid Build Coastguard Worker // The unrelated process should still be running.
261*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(TEMP_FAILURE_RETRY(waitid(P_PID, pid_2, &info, WEXITED | WNOWAIT | WNOHANG)), 0);
262*795d594fSAndroid Build Coastguard Worker EXPECT_EQ(info.si_signo, 0);
263*795d594fSAndroid Build Coastguard Worker }
264*795d594fSAndroid Build Coastguard Worker
265*795d594fSAndroid Build Coastguard Worker } // namespace
266*795d594fSAndroid Build Coastguard Worker } // namespace tools
267*795d594fSAndroid Build Coastguard Worker } // namespace art
268