kernel_wrap_test.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The linux host build of nacl_io can't do wrapping of syscalls so all
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// these tests must be disabled.
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if !defined(__linux__)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <unistd.h>
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string>
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector>
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "gtest/gtest.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "mock_kernel_proxy.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "nacl_io/kernel_intercept.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/kernel_wrap.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/kernel_wrap_real.h"
194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/osmman.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/ossocket.h"
214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "nacl_io/ostermios.h"
224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(__native_client__) && !defined(__GLIBC__)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)extern "C" {
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// TODO(sbc): remove once these get added to the newlib toolchain headers.
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)int fchdir(int fd);
27int utimes(const char *filename, const struct timeval times[2]);
28}
29#endif
30
31using namespace nacl_io;
32
33using ::testing::_;
34using ::testing::AnyNumber;
35using ::testing::DoAll;
36using ::testing::Invoke;
37using ::testing::Return;
38using ::testing::StrEq;
39
40namespace {
41
42#define COMPARE_FIELD(f)                                                     \
43  if (arg->f != statbuf->f) {                                                \
44    *result_listener << "mismatch of field \"" #f                            \
45                        "\". "                                               \
46                        "expected: " << statbuf->f << " actual: " << arg->f; \
47    return false;                                                            \
48  }
49
50MATCHER_P(IsEqualToStatbuf, statbuf, "") {
51  COMPARE_FIELD(st_dev);
52  COMPARE_FIELD(st_ino);
53  COMPARE_FIELD(st_mode);
54  COMPARE_FIELD(st_nlink);
55  COMPARE_FIELD(st_uid);
56  COMPARE_FIELD(st_gid);
57  COMPARE_FIELD(st_rdev);
58  COMPARE_FIELD(st_size);
59  COMPARE_FIELD(st_atime);
60  COMPARE_FIELD(st_mtime);
61  COMPARE_FIELD(st_ctime);
62  return true;
63}
64
65#undef COMPARE_FIELD
66
67ACTION_P(SetErrno, value) {
68  errno = value;
69}
70
71ACTION_P2(SetString, target, source) {
72  strcpy(target, source);
73}
74
75ACTION_P(SetStat, statbuf) {
76  memset(arg1, 0, sizeof(struct stat));
77  arg1->st_dev = statbuf->st_dev;
78  arg1->st_ino = statbuf->st_ino;
79  arg1->st_mode = statbuf->st_mode;
80  arg1->st_nlink = statbuf->st_nlink;
81  arg1->st_uid = statbuf->st_uid;
82  arg1->st_gid = statbuf->st_gid;
83  arg1->st_rdev = statbuf->st_rdev;
84  arg1->st_size = statbuf->st_size;
85  arg1->st_atime = statbuf->st_atime;
86  arg1->st_mtime = statbuf->st_mtime;
87  arg1->st_ctime = statbuf->st_ctime;
88}
89
90void MakeDummyStatbuf(struct stat* statbuf) {
91  memset(&statbuf[0], 0, sizeof(struct stat));
92  statbuf->st_dev = 1;
93  statbuf->st_ino = 2;
94  statbuf->st_mode = 3;
95  statbuf->st_nlink = 4;
96  statbuf->st_uid = 5;
97  statbuf->st_gid = 6;
98  statbuf->st_rdev = 7;
99  statbuf->st_size = 8;
100  statbuf->st_atime = 9;
101  statbuf->st_mtime = 10;
102  statbuf->st_ctime = 11;
103}
104
105const mode_t kDummyMode = 0xbeef;
106const int kDummyErrno = 0xfeeb;
107const int kDummyInt = 0xdedbeef;
108const int kDummyInt2 = 0xcabba6e;
109const int kDummyInt3 = 0xf00ba4;
110const int kDummyInt4 = 0xabacdba;
111const size_t kDummySizeT = 0x60067e;
112const char* kDummyConstChar = "foobar";
113const char* kDummyConstChar2 = "g00gl3";
114const char* kDummyConstChar3 = "fr00gl3";
115const void* kDummyVoidPtr = "blahblah";
116const uid_t kDummyUid = 1001;
117const gid_t kDummyGid = 1002;
118
119class KernelWrapTest : public ::testing::Test {
120 public:
121  KernelWrapTest() {}
122
123  virtual void SetUp() {
124    // Initialize the global errno value to a consistent value rather than
125    // relying on its value from previous test runs.
126    errno = 0;
127
128    // Initializing the KernelProxy opens stdin/stdout/stderr.
129    EXPECT_CALL(mock, open(_, _))
130        .WillOnce(Return(0))
131        .WillOnce(Return(1))
132        .WillOnce(Return(2));
133
134    ASSERT_EQ(0, ki_push_state_for_testing());
135    ASSERT_EQ(0, ki_init(&mock));
136
137    // We allow write to be called any number of times, and it forwards to
138    // _real_write. This prevents an infinite loop writing output if there is a
139    // failure.
140    ON_CALL(mock, write(_, _, _))
141        .WillByDefault(Invoke(this, &KernelWrapTest::DefaultWrite));
142    EXPECT_CALL(mock, write(_, _, _)).Times(AnyNumber());
143  }
144
145  void TearDown() {
146    // Uninitialize the kernel proxy so wrapped functions passthrough to their
147    // unwrapped versions.
148    ki_uninit();
149  }
150
151  MockKernelProxy mock;
152
153 private:
154  ssize_t DefaultWrite(int fd, const void* buf, size_t count) {
155   assert(fd <= 2);
156   size_t nwrote;
157   int rtn = _real_write(fd, buf, count, &nwrote);
158   if (rtn != 0) {
159     errno = rtn;
160     return -1;
161   }
162   return nwrote;
163  }
164};
165
166}  // namespace
167
168TEST_F(KernelWrapTest, access) {
169  EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt)) .WillOnce(Return(0));
170  EXPECT_EQ(0, access(kDummyConstChar, kDummyInt));
171
172  EXPECT_CALL(mock, access(kDummyConstChar, kDummyInt))
173      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
174  EXPECT_EQ(-1, access(kDummyConstChar, kDummyInt));
175  EXPECT_EQ(kDummyErrno, errno);
176
177}
178
179TEST_F(KernelWrapTest, chdir) {
180  EXPECT_CALL(mock, chdir(kDummyConstChar)).WillOnce(Return(0));
181  EXPECT_EQ(0, chdir(kDummyConstChar));
182
183  EXPECT_CALL(mock, chdir(kDummyConstChar))
184    .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
185  EXPECT_EQ(-1, chdir(kDummyConstChar));
186  ASSERT_EQ(kDummyErrno, errno);
187}
188
189TEST_F(KernelWrapTest, chmod) {
190  EXPECT_CALL(mock, chmod(kDummyConstChar, kDummyMode))
191      .WillOnce(Return(kDummyInt2));
192  EXPECT_EQ(kDummyInt2,chmod(kDummyConstChar, kDummyMode));
193}
194
195TEST_F(KernelWrapTest, chown) {
196  EXPECT_CALL(mock, chown(kDummyConstChar, kDummyUid, kDummyGid))
197      .WillOnce(Return(kDummyInt));
198  EXPECT_EQ(kDummyInt, chown(kDummyConstChar, kDummyUid, kDummyGid));
199}
200
201TEST_F(KernelWrapTest, close) {
202  // The way we wrap close does not support returning arbitrary values, so we
203  // test 0 and -1.
204  EXPECT_CALL(mock, close(kDummyInt))
205      .WillOnce(Return(0));
206
207  EXPECT_EQ(0, close(kDummyInt));
208
209  EXPECT_CALL(mock, close(kDummyInt))
210      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
211  EXPECT_EQ(-1, close(kDummyInt));
212  ASSERT_EQ(kDummyErrno, errno);
213}
214
215TEST_F(KernelWrapTest, dup) {
216  EXPECT_CALL(mock, dup(kDummyInt)).WillOnce(Return(kDummyInt2));
217  EXPECT_EQ(kDummyInt2, dup(kDummyInt));
218}
219
220TEST_F(KernelWrapTest, dup2) {
221  // The way we wrap dup2 does not support returning aribtrary values, only -1
222  // or the value of the new fd.
223  EXPECT_CALL(mock, dup2(kDummyInt, kDummyInt2))
224      .WillOnce(Return(kDummyInt2))
225      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
226
227  EXPECT_EQ(kDummyInt2, dup2(kDummyInt, kDummyInt2));
228  EXPECT_EQ(-1, dup2(kDummyInt, kDummyInt2));
229  ASSERT_EQ(kDummyErrno, errno);
230}
231
232TEST_F(KernelWrapTest, fchdir) {
233  EXPECT_CALL(mock, fchdir(kDummyInt))
234      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
235
236  EXPECT_EQ(-1, fchdir(kDummyInt));
237  ASSERT_EQ(kDummyErrno, errno);
238}
239
240TEST_F(KernelWrapTest, fchmod) {
241  EXPECT_CALL(mock, fchmod(kDummyInt, kDummyMode))
242      .WillOnce(Return(0))
243      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
244
245  EXPECT_EQ(0, fchmod(kDummyInt, kDummyMode));
246  EXPECT_EQ(-1, fchmod(kDummyInt, kDummyMode));
247  ASSERT_EQ(kDummyErrno, errno);
248}
249
250TEST_F(KernelWrapTest, fchown) {
251  EXPECT_CALL(mock, fchown(kDummyInt, kDummyUid, kDummyGid))
252      .WillOnce(Return(kDummyInt));
253  EXPECT_EQ(kDummyInt, fchown(kDummyInt, kDummyUid, kDummyGid));
254}
255
256TEST_F(KernelWrapTest, fcntl) {
257  char buffer[] = "fcntl";
258  EXPECT_CALL(mock, fcntl(kDummyInt, kDummyInt2, _))
259      .WillOnce(Return(kDummyInt3));
260  EXPECT_EQ(kDummyInt3, fcntl(kDummyInt, kDummyInt2, buffer));
261}
262
263TEST_F(KernelWrapTest, fdatasync) {
264  EXPECT_CALL(mock, fdatasync(kDummyInt)).WillOnce(Return(0))
265      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
266
267  EXPECT_EQ(0, fdatasync(kDummyInt));
268  EXPECT_EQ(-1, fdatasync(kDummyInt));
269  ASSERT_EQ(kDummyErrno, errno);
270}
271
272TEST_F(KernelWrapTest, fstat) {
273  // The way we wrap fstat does not support returning aribtrary values, only 0
274  // or -1.
275  struct stat in_statbuf;
276  MakeDummyStatbuf(&in_statbuf);
277  EXPECT_CALL(mock, fstat(kDummyInt, _))
278      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
279      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
280  struct stat out_statbuf;
281
282  EXPECT_EQ(0, fstat(kDummyInt, &out_statbuf));
283  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
284
285  EXPECT_EQ(-1, fstat(kDummyInt, &out_statbuf));
286  ASSERT_EQ(kDummyErrno, errno);
287}
288
289TEST_F(KernelWrapTest, ftruncate) {
290  EXPECT_CALL(mock, ftruncate(kDummyInt, kDummyInt2))
291      .WillOnce(Return(kDummyInt3));
292  EXPECT_EQ(kDummyInt3, ftruncate(kDummyInt, kDummyInt2));
293}
294
295TEST_F(KernelWrapTest, fsync) {
296  EXPECT_CALL(mock, fsync(kDummyInt))
297      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
298  EXPECT_EQ(-1, fsync(kDummyInt));
299  ASSERT_EQ(kDummyErrno, errno);
300}
301
302TEST_F(KernelWrapTest, getcwd) {
303  char buffer[PATH_MAX];
304  char result[PATH_MAX];
305  memset(buffer, 0, PATH_MAX);
306  strcpy(result, "getcwd_result");
307  EXPECT_CALL(mock, getcwd(buffer, kDummySizeT))
308       .WillOnce(DoAll(SetString(buffer, result), Return(buffer)));
309  EXPECT_STREQ(result, getcwd(buffer, kDummySizeT));
310}
311
312TEST_F(KernelWrapTest, getdents) {
313#if !defined( __GLIBC__) && !defined(__BIONIC__)
314  // TODO(sbc): Find a way to test the getdents wrapper under glibc.
315  // It looks like the only way to exercise it is to call readdir(2).
316  // There is an internal glibc function __getdents that will call the
317  // IRT but that cannot be accessed from here as glibc does not export it.
318  int dummy_val;
319  void* void_ptr = &dummy_val;
320  EXPECT_CALL(mock, getdents(kDummyInt, void_ptr, kDummyInt2))
321      .WillOnce(Return(kDummyInt2));
322  EXPECT_EQ(kDummyInt2, getdents(kDummyInt, void_ptr, kDummyInt2));
323#endif
324}
325
326// gcc gives error: getwd is deprecated.
327#if defined(__GNUC__)
328#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
329#endif
330TEST_F(KernelWrapTest, getwd) {
331  char result[] = "getwd_result";
332  char buffer[] = "getwd";
333  EXPECT_CALL(mock, getwd(buffer)).WillOnce(Return(result));
334  EXPECT_EQ(result, getwd(buffer));
335}
336#if defined(__GNUC__)
337#pragma GCC diagnostic warning "-Wdeprecated-declarations"
338#endif
339
340TEST_F(KernelWrapTest, ioctl) {
341  char buffer[] = "ioctl";
342  EXPECT_CALL(mock, ioctl(kDummyInt, kDummyInt2, _))
343      .WillOnce(Return(kDummyInt3));
344  EXPECT_EQ(kDummyInt3, ioctl(kDummyInt, kDummyInt2, buffer));
345}
346
347#if !defined(__BIONIC__)
348TEST_F(KernelWrapTest, isatty) {
349  EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(kDummyInt2));
350  EXPECT_EQ(kDummyInt2, isatty(kDummyInt));
351
352  // This test verifies that the IRT interception wrapper for isatty
353  // ignores the value of errno when isatty() returns 1.  We had a bug
354  // where returning 1 from ki_isatty resulted in errno being returned
355  // by the IRT interface.
356  errno = kDummyInt3;
357  EXPECT_CALL(mock, isatty(kDummyInt)).WillOnce(Return(1));
358  EXPECT_EQ(1, isatty(kDummyInt));
359}
360#endif
361
362TEST_F(KernelWrapTest, kill) {
363  EXPECT_CALL(mock, kill(kDummyInt, kDummyInt2)).WillOnce(Return(kDummyInt3));
364  EXPECT_EQ(kDummyInt3, kill(kDummyInt, kDummyInt2));
365}
366
367TEST_F(KernelWrapTest, lchown) {
368  EXPECT_CALL(mock, lchown(kDummyConstChar, kDummyUid, kDummyGid))
369      .WillOnce(Return(kDummyInt));
370  EXPECT_EQ(kDummyInt, lchown(kDummyConstChar, kDummyUid, kDummyGid));
371}
372
373TEST_F(KernelWrapTest, link) {
374  EXPECT_CALL(mock, link(kDummyConstChar, kDummyConstChar2))
375      .WillOnce(Return(kDummyInt));
376  EXPECT_EQ(kDummyInt, link(kDummyConstChar, kDummyConstChar2));
377}
378
379TEST_F(KernelWrapTest, lseek) {
380  EXPECT_CALL(mock, lseek(kDummyInt, kDummyInt2, kDummyInt3))
381      .WillOnce(Return(kDummyInt4));
382  EXPECT_EQ(kDummyInt4, lseek(kDummyInt, kDummyInt2, kDummyInt3));
383}
384
385TEST_F(KernelWrapTest, mkdir) {
386#if defined(WIN32)
387  EXPECT_CALL(mock, mkdir(kDummyConstChar, 0777)).WillOnce(Return(kDummyInt2));
388  EXPECT_EQ(kDummyInt2, mkdir(kDummyConstChar));
389#else
390  EXPECT_CALL(mock, mkdir(kDummyConstChar, kDummyMode))
391      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
392  EXPECT_EQ(-1, mkdir(kDummyConstChar, kDummyMode));
393  ASSERT_EQ(kDummyErrno, errno);
394#endif
395}
396
397TEST_F(KernelWrapTest, mmap) {
398  // We only wrap mmap if |flags| has the MAP_ANONYMOUS bit unset.
399  int flags = kDummyInt2 & ~MAP_ANONYMOUS;
400
401  const size_t kDummySizeT2 = 0xbadf00d;
402  int dummy1 = 123;
403  int dummy2 = 456;
404  void* kDummyVoidPtr1 = &dummy1;
405  void* kDummyVoidPtr2 = &dummy2;
406  EXPECT_CALL(mock,
407              mmap(kDummyVoidPtr1,
408                   kDummySizeT,
409                   kDummyInt,
410                   flags,
411                   kDummyInt3,
412                   kDummySizeT2)).WillOnce(Return(kDummyVoidPtr2));
413  EXPECT_EQ(kDummyVoidPtr2,
414            mmap(kDummyVoidPtr1,
415                 kDummySizeT,
416                 kDummyInt,
417                 flags,
418                 kDummyInt3,
419                 kDummySizeT2));
420}
421
422TEST_F(KernelWrapTest, mount) {
423  EXPECT_CALL(mock,
424              mount(kDummyConstChar,
425                    kDummyConstChar2,
426                    kDummyConstChar3,
427                    kDummyInt,
428                    kDummyVoidPtr)).WillOnce(Return(kDummyInt2));
429  EXPECT_EQ(kDummyInt2,
430            mount(kDummyConstChar,
431                  kDummyConstChar2,
432                  kDummyConstChar3,
433                  kDummyInt,
434                  kDummyVoidPtr));
435}
436
437TEST_F(KernelWrapTest, munmap) {
438  // The way we wrap munmap, calls the "real" mmap as well as the intercepted
439  // one. The result returned is from the "real" mmap.
440  int dummy1 = 123;
441  void* kDummyVoidPtr = &dummy1;
442  size_t kDummySizeT = sizeof(kDummyVoidPtr);
443  EXPECT_CALL(mock, munmap(kDummyVoidPtr, kDummySizeT));
444  munmap(kDummyVoidPtr, kDummySizeT);
445}
446
447TEST_F(KernelWrapTest, open) {
448  // We pass O_RDONLY because we do not want an error in flags translation
449  EXPECT_CALL(mock, open(kDummyConstChar, 0))
450      .WillOnce(Return(kDummyInt2))
451      .WillOnce(Return(kDummyInt2));
452
453  EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0));
454  EXPECT_EQ(kDummyInt2, open(kDummyConstChar, 0));
455}
456
457TEST_F(KernelWrapTest, pipe) {
458  int fds[] = {1, 2};
459  EXPECT_CALL(mock, pipe(fds)).WillOnce(Return(kDummyInt));
460  EXPECT_EQ(kDummyInt, pipe(fds));
461}
462
463TEST_F(KernelWrapTest, read) {
464  int dummy_value;
465  void* dummy_void_ptr = &dummy_value;
466  EXPECT_CALL(mock, read(kDummyInt, dummy_void_ptr, kDummyInt2))
467      .WillOnce(Return(kDummyInt3));
468  EXPECT_EQ(kDummyInt3, read(kDummyInt, dummy_void_ptr, kDummyInt2));
469}
470
471TEST_F(KernelWrapTest, readlink) {
472  char buf[10];
473
474  EXPECT_CALL(mock, readlink(kDummyConstChar, buf, 10))
475      .WillOnce(Return(kDummyInt))
476      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
477
478  EXPECT_EQ(kDummyInt, readlink(kDummyConstChar, buf, 10));
479  EXPECT_EQ(-1, readlink(kDummyConstChar, buf, 10));
480  ASSERT_EQ(kDummyErrno, errno);
481}
482
483#ifdef __GLIBC__
484// Under newlib there is no remove syscall.  Instead it is implemented
485// in terms of unlink()/rmdir().
486TEST_F(KernelWrapTest, remove) {
487  EXPECT_CALL(mock, remove(kDummyConstChar)).WillOnce(Return(-1));
488  EXPECT_EQ(-1, remove(kDummyConstChar));
489}
490#endif
491
492TEST_F(KernelWrapTest, rename) {
493  EXPECT_CALL(mock, rename(kDummyConstChar, kDummyConstChar2))
494      .WillOnce(Return(0))
495      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
496
497  EXPECT_EQ(0, rename(kDummyConstChar, kDummyConstChar2));
498  EXPECT_EQ(-1, rename(kDummyConstChar, kDummyConstChar2));
499  ASSERT_EQ(kDummyErrno, errno);
500}
501
502TEST_F(KernelWrapTest, rmdir) {
503  EXPECT_CALL(mock, rmdir(kDummyConstChar))
504      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
505  EXPECT_EQ(-1, rmdir(kDummyConstChar));
506  ASSERT_EQ(kDummyErrno, errno);
507}
508
509static void new_handler(int) {}
510
511TEST_F(KernelWrapTest, sigaction) {
512  struct sigaction action;
513  struct sigaction oaction;
514  EXPECT_CALL(mock, sigaction(kDummyInt, &action, &oaction))
515      .WillOnce(Return(0));
516  EXPECT_EQ(0, sigaction(kDummyInt, &action, &oaction));
517}
518
519TEST_F(KernelWrapTest, sigset) {
520  EXPECT_CALL(mock, sigaction(kDummyInt, _, _))
521      .WillOnce(Return(0));
522  EXPECT_EQ(NULL, sigset(kDummyInt, new_handler));
523}
524
525TEST_F(KernelWrapTest, signal) {
526  // KernelIntercept forwards calls to signal to KernelProxy::sigset.
527  EXPECT_CALL(mock, sigaction(kDummyInt, _, _))
528      .WillOnce(Return(0));
529  EXPECT_EQ(NULL, signal(kDummyInt, new_handler));
530}
531
532TEST_F(KernelWrapTest, stat) {
533  // The way we wrap stat does not support returning aribtrary values, only 0
534  // or -1.
535  struct stat in_statbuf;
536  MakeDummyStatbuf(&in_statbuf);
537  EXPECT_CALL(mock, stat(StrEq(kDummyConstChar), _))
538      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
539      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
540  struct stat out_statbuf;
541
542  EXPECT_EQ(0, stat(kDummyConstChar, &out_statbuf));
543  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
544
545  EXPECT_EQ(-1, stat(kDummyConstChar, &out_statbuf));
546  ASSERT_EQ(kDummyErrno, errno);
547}
548
549TEST_F(KernelWrapTest, symlink) {
550  EXPECT_CALL(mock, symlink(kDummyConstChar, kDummyConstChar2))
551      .WillOnce(Return(kDummyInt));
552  EXPECT_EQ(kDummyInt, symlink(kDummyConstChar, kDummyConstChar2));
553}
554
555#ifndef __BIONIC__
556TEST_F(KernelWrapTest, tcflush) {
557  EXPECT_CALL(mock, tcflush(kDummyInt, kDummyInt2))
558      .WillOnce(Return(kDummyInt3));
559  EXPECT_EQ(kDummyInt3, tcflush(kDummyInt, kDummyInt2));
560}
561
562TEST_F(KernelWrapTest, tcgetattr) {
563  struct termios term;
564  EXPECT_CALL(mock, tcgetattr(kDummyInt, &term)).WillOnce(Return(kDummyInt2));
565  EXPECT_EQ(kDummyInt2, tcgetattr(kDummyInt, &term));
566}
567
568TEST_F(KernelWrapTest, tcsetattr) {
569  struct termios term;
570  EXPECT_CALL(mock, tcsetattr(kDummyInt, kDummyInt2, &term))
571      .WillOnce(Return(kDummyInt3));
572  EXPECT_EQ(kDummyInt3, tcsetattr(kDummyInt, kDummyInt2, &term));
573}
574#endif
575
576TEST_F(KernelWrapTest, umount) {
577  EXPECT_CALL(mock, umount(kDummyConstChar)).WillOnce(Return(kDummyInt));
578  EXPECT_EQ(kDummyInt, umount(kDummyConstChar));
579}
580
581TEST_F(KernelWrapTest, truncate) {
582  EXPECT_CALL(mock, truncate(kDummyConstChar, kDummyInt3))
583      .WillOnce(Return(0))
584      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
585
586  EXPECT_EQ(0, truncate(kDummyConstChar, kDummyInt3));
587
588  EXPECT_EQ(-1, truncate(kDummyConstChar, kDummyInt3));
589}
590
591TEST_F(KernelWrapTest, lstat) {
592  struct stat in_statbuf;
593  MakeDummyStatbuf(&in_statbuf);
594  EXPECT_CALL(mock, lstat(StrEq(kDummyConstChar), _))
595      .WillOnce(DoAll(SetStat(&in_statbuf), Return(0)))
596      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
597  struct stat out_statbuf;
598
599  EXPECT_EQ(0, lstat(kDummyConstChar, &out_statbuf));
600  EXPECT_THAT(&in_statbuf, IsEqualToStatbuf(&out_statbuf));
601
602  EXPECT_EQ(-1, lstat(kDummyConstChar, &out_statbuf));
603  ASSERT_EQ(kDummyErrno, errno);
604}
605
606TEST_F(KernelWrapTest, unlink) {
607  EXPECT_CALL(mock, unlink(kDummyConstChar))
608      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
609  EXPECT_EQ(-1, unlink(kDummyConstChar));
610  ASSERT_EQ(kDummyErrno, errno);
611}
612
613TEST_F(KernelWrapTest, utime) {
614  const struct utimbuf* times = NULL;
615  EXPECT_CALL(mock, utime(kDummyConstChar, times)).WillOnce(Return(kDummyInt));
616  EXPECT_EQ(kDummyInt, utime(kDummyConstChar, times));
617}
618
619TEST_F(KernelWrapTest, utimes) {
620  struct timeval* times = NULL;
621  EXPECT_CALL(mock, utimes(kDummyConstChar, times))
622      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
623  EXPECT_EQ(-1, utimes(kDummyConstChar, times));
624  ASSERT_EQ(kDummyErrno, errno);
625}
626
627TEST_F(KernelWrapTest, write) {
628  EXPECT_CALL(mock, write(kDummyInt, kDummyVoidPtr, kDummyInt2))
629      .WillOnce(Return(kDummyInt3));
630  EXPECT_EQ(kDummyInt3, write(kDummyInt, kDummyVoidPtr, kDummyInt2));
631}
632
633#if defined(PROVIDES_SOCKET_API) and !defined(__BIONIC__)
634TEST_F(KernelWrapTest, poll) {
635  struct pollfd fds;
636  EXPECT_CALL(mock, poll(&fds, kDummyInt, kDummyInt2))
637      .WillOnce(Return(kDummyInt3));
638  EXPECT_EQ(kDummyInt3, poll(&fds, kDummyInt, kDummyInt2));
639}
640
641TEST_F(KernelWrapTest, select) {
642  fd_set readfds;
643  fd_set writefds;
644  fd_set exceptfds;
645  EXPECT_CALL(mock, select(kDummyInt, &readfds, &writefds, &exceptfds, NULL))
646      .WillOnce(Return(kDummyInt2));
647  EXPECT_EQ(kDummyInt2,
648            select(kDummyInt, &readfds, &writefds, &exceptfds, NULL));
649}
650
651// Socket Functions
652TEST_F(KernelWrapTest, accept) {
653  struct sockaddr addr;
654  socklen_t len;
655  EXPECT_CALL(mock, accept(kDummyInt, &addr, &len))
656      .WillOnce(Return(kDummyInt2));
657  EXPECT_EQ(kDummyInt2, accept(kDummyInt, &addr, &len));
658}
659
660TEST_F(KernelWrapTest, bind) {
661  // The way we wrap bind does not support returning arbitrary values, so we
662  // test 0 and -1.
663  struct sockaddr addr;
664  EXPECT_CALL(mock, bind(kDummyInt, &addr, kDummyInt2))
665      .WillOnce(Return(0))
666      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
667  EXPECT_EQ(0, bind(kDummyInt, &addr, kDummyInt2));
668  EXPECT_EQ(-1, bind(kDummyInt, &addr, kDummyInt2));
669  EXPECT_EQ(kDummyErrno, errno);
670}
671
672TEST_F(KernelWrapTest, connect) {
673  // The way we wrap connect does not support returning arbitrary values, so we
674  // test 0 and -1.
675  struct sockaddr addr;
676  EXPECT_CALL(mock, connect(kDummyInt, &addr, kDummyInt2))
677      .WillOnce(Return(0))
678      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
679  EXPECT_EQ(0, connect(kDummyInt, &addr, kDummyInt2));
680  EXPECT_EQ(-1, connect(kDummyInt, &addr, kDummyInt2));
681  EXPECT_EQ(kDummyErrno, errno);
682}
683
684TEST_F(KernelWrapTest, gethostbyname) {
685  struct hostent result;
686  EXPECT_CALL(mock, gethostbyname(kDummyConstChar)).WillOnce(Return(&result));
687  EXPECT_EQ(&result, gethostbyname(kDummyConstChar));
688}
689
690TEST_F(KernelWrapTest, getpeername) {
691  // The way we wrap getpeername does not support returning arbitrary values,
692  // so we test 0 and -1.
693  struct sockaddr addr;
694  socklen_t len;
695  EXPECT_CALL(mock, getpeername(kDummyInt, &addr, &len))
696      .WillOnce(Return(0))
697      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
698  EXPECT_EQ(0, getpeername(kDummyInt, &addr, &len));
699  EXPECT_EQ(-1, getpeername(kDummyInt, &addr, &len));
700  EXPECT_EQ(kDummyErrno, errno);
701}
702
703TEST_F(KernelWrapTest, getsockname) {
704  // The way we wrap getsockname does not support returning arbitrary values,
705  // so we test 0 and -1.
706  struct sockaddr addr;
707  socklen_t len;
708
709  EXPECT_CALL(mock, getsockname(kDummyInt, &addr, &len))
710      .WillOnce(Return(0))
711      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
712  EXPECT_EQ(0, getsockname(kDummyInt, &addr, &len));
713  EXPECT_EQ(-1, getsockname(kDummyInt, &addr, &len));
714  EXPECT_EQ(kDummyErrno, errno);
715}
716
717TEST_F(KernelWrapTest, getsockopt) {
718  // The way we wrap getsockname does not support returning arbitrary values,
719  // so we test 0 and -1.
720  int dummy_val;
721  void* dummy_void_ptr = &dummy_val;
722  socklen_t len;
723  EXPECT_CALL(
724      mock, getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len))
725      .WillOnce(Return(0))
726      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
727  EXPECT_EQ(
728      0,
729      getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len));
730  EXPECT_EQ(
731      -1,
732      getsockopt(kDummyInt, kDummyInt2, kDummyInt3, dummy_void_ptr, &len));
733  EXPECT_EQ(kDummyErrno, errno);
734}
735
736TEST_F(KernelWrapTest, listen) {
737  // The way we wrap listen does not support returning arbitrary values, so we
738  // test 0 and -1.
739  EXPECT_CALL(mock, listen(kDummyInt, kDummyInt2))
740      .WillOnce(Return(0))
741      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
742  EXPECT_EQ(0, listen(kDummyInt, kDummyInt2));
743  EXPECT_EQ(-1, listen(kDummyInt, kDummyInt2));
744  EXPECT_EQ(kDummyErrno, errno);
745}
746
747TEST_F(KernelWrapTest, recv) {
748  int dummy_val;
749  void* dummy_void_ptr = &dummy_val;
750  EXPECT_CALL(mock, recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2))
751      .WillOnce(Return(kDummyInt3));
752  EXPECT_EQ(kDummyInt3,
753            recv(kDummyInt, dummy_void_ptr, kDummySizeT, kDummyInt2));
754}
755
756TEST_F(KernelWrapTest, recvfrom) {
757  int dummy_val;
758  void* dummy_void_ptr = &dummy_val;
759  struct sockaddr addr;
760  socklen_t len;
761  EXPECT_CALL(
762      mock,
763      recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len))
764      .WillOnce(Return(kDummyInt4));
765  EXPECT_EQ(
766      kDummyInt4,
767      recvfrom(kDummyInt, dummy_void_ptr, kDummyInt2, kDummyInt3, &addr, &len));
768}
769
770#ifndef __BIONIC__
771TEST_F(KernelWrapTest, recvmsg) {
772  struct msghdr msg;
773  EXPECT_CALL(mock, recvmsg(kDummyInt, &msg, kDummyInt2))
774      .WillOnce(Return(kDummyInt3));
775  EXPECT_EQ(kDummyInt3, recvmsg(kDummyInt, &msg, kDummyInt2));
776}
777#endif
778
779TEST_F(KernelWrapTest, send) {
780  EXPECT_CALL(mock, send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2))
781      .WillOnce(Return(kDummyInt3));
782  EXPECT_EQ(kDummyInt3,
783            send(kDummyInt, kDummyVoidPtr, kDummySizeT, kDummyInt2));
784}
785
786TEST_F(KernelWrapTest, sendto) {
787  const socklen_t kDummySockLen = 0x50cc5;
788  struct sockaddr addr;
789  EXPECT_CALL(mock,
790              sendto(kDummyInt,
791                     kDummyVoidPtr,
792                     kDummyInt2,
793                     kDummyInt3,
794                     &addr,
795                     kDummySockLen)).WillOnce(Return(kDummyInt4));
796  EXPECT_EQ(kDummyInt4,
797            sendto(kDummyInt,
798                   kDummyVoidPtr,
799                   kDummyInt2,
800                   kDummyInt3,
801                   &addr,
802                   kDummySockLen));
803}
804
805TEST_F(KernelWrapTest, sendmsg) {
806  struct msghdr msg;
807  EXPECT_CALL(mock, sendmsg(kDummyInt, &msg, kDummyInt2))
808      .WillOnce(Return(kDummyInt3));
809  EXPECT_EQ(kDummyInt3, sendmsg(kDummyInt, &msg, kDummyInt2));
810}
811
812TEST_F(KernelWrapTest, setsockopt) {
813  // The way we wrap setsockopt does not support returning arbitrary values, so
814  // we test 0 and -1.
815  const socklen_t kDummySockLen = 0x50cc5;
816  EXPECT_CALL(
817      mock,
818      setsockopt(
819          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen))
820      .WillOnce(Return(0))
821      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
822  EXPECT_EQ(
823      0,
824      setsockopt(
825          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen));
826  EXPECT_EQ(
827      -1,
828      setsockopt(
829          kDummyInt, kDummyInt2, kDummyInt3, kDummyVoidPtr, kDummySockLen));
830  EXPECT_EQ(kDummyErrno, errno);
831}
832
833TEST_F(KernelWrapTest, shutdown) {
834  // The way we wrap shutdown does not support returning arbitrary values, so we
835  // test 0 and -1.
836  EXPECT_CALL(mock, shutdown(kDummyInt, kDummyInt2))
837      .WillOnce(Return(0))
838      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
839  EXPECT_EQ(0, shutdown(kDummyInt, kDummyInt2));
840  EXPECT_EQ(-1, shutdown(kDummyInt, kDummyInt2));
841  EXPECT_EQ(kDummyErrno, errno);
842}
843
844TEST_F(KernelWrapTest, socket) {
845  EXPECT_CALL(mock, socket(kDummyInt, kDummyInt2, kDummyInt3))
846      .WillOnce(Return(kDummyInt4));
847  EXPECT_EQ(kDummyInt4, socket(kDummyInt, kDummyInt2, kDummyInt3));
848}
849
850TEST_F(KernelWrapTest, socketpair) {
851  // The way we wrap socketpair does not support returning arbitrary values,
852  // so we test 0 and -1.
853  int dummy_val;
854  EXPECT_CALL(mock, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val))
855      .WillOnce(Return(0))
856      .WillOnce(DoAll(SetErrno(kDummyErrno), Return(-1)));
857  EXPECT_EQ(0, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val));
858  EXPECT_EQ(-1, socketpair(kDummyInt, kDummyInt2, kDummyInt3, &dummy_val));
859  EXPECT_EQ(kDummyErrno, errno);
860}
861
862#endif  // PROVIDES_SOCKET_API
863
864#endif  // __linux__
865