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