1 // Copyright (c) 2014 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 #include <errno.h> 6 #include <limits.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <sys/stat.h> 10 11 #include "gtest/gtest.h" 12 13 #include "nacl_io/kernel_intercept.h" 14 #include "nacl_io/kernel_proxy.h" 15 16 using namespace nacl_io; 17 18 namespace { 19 20 class SyscallsTest : public ::testing::Test { 21 public: 22 SyscallsTest() {} 23 24 void SetUp() { 25 ASSERT_EQ(0, ki_push_state_for_testing()); 26 ASSERT_EQ(0, ki_init(&kp_)); 27 // Unmount the passthrough FS and mount a memfs. 28 EXPECT_EQ(0, kp_.umount("/")); 29 EXPECT_EQ(0, kp_.mount("", "/", "memfs", 0, NULL)); 30 } 31 32 void TearDown() { ki_uninit(); } 33 34 protected: 35 KernelProxy kp_; 36 }; 37 38 } // namespace 39 40 #if defined(__native_client__) || defined(STANDALONE) 41 42 // The Linux standalone test is unique in that it calls the real Linux 43 // functions (realpath, mkdir, chdir, etc.), not the nacl_io functions. This is 44 // done to show that the tests match the behavior for a real implementation. 45 46 TEST_F(SyscallsTest, Realpath) { 47 char buffer[PATH_MAX]; 48 int result; 49 50 #if defined(__native_client__) 51 ASSERT_EQ(0, mkdir("/tmp", S_IREAD | S_IWRITE)); 52 #endif 53 54 result = mkdir("/tmp/bar", S_IREAD | S_IWRITE); 55 #if defined(__native_client__) 56 ASSERT_EQ(0, result); 57 #else 58 if (result == -1) { 59 ASSERT_EQ(EEXIST, errno); 60 } else { 61 ASSERT_EQ(0, result); 62 } 63 #endif 64 65 int fd = open("/tmp/file", O_CREAT | O_RDWR, 0644); 66 ASSERT_GT(fd, -1); 67 ASSERT_EQ(0, close(fd)); 68 69 // Test absolute paths. 70 EXPECT_STREQ("/", realpath("/", buffer)); 71 EXPECT_STREQ("/", realpath("/tmp/..", buffer)); 72 EXPECT_STREQ("/tmp", realpath("/tmp", buffer)); 73 EXPECT_STREQ("/tmp", realpath("/tmp/", buffer)); 74 EXPECT_STREQ("/tmp", realpath("/tmp/bar/..", buffer)); 75 EXPECT_STREQ("/tmp", realpath("/tmp/bar/../bar/../../tmp", buffer)); 76 EXPECT_STREQ("/tmp", realpath("/tmp/././", buffer)); 77 EXPECT_STREQ("/tmp", realpath("///tmp", buffer)); 78 EXPECT_STREQ("/tmp/bar", realpath("/tmp/bar", buffer)); 79 80 EXPECT_EQ(NULL, realpath("/blah", buffer)); 81 EXPECT_EQ(ENOENT, errno); 82 83 EXPECT_EQ(NULL, realpath("/blah/blah", buffer)); 84 EXPECT_EQ(ENOENT, errno); 85 86 EXPECT_EQ(NULL, realpath("/tmp/baz/..", buffer)); 87 EXPECT_EQ(ENOENT, errno); 88 89 EXPECT_EQ(NULL, realpath("/tmp/file/", buffer)); 90 EXPECT_EQ(ENOTDIR, errno); 91 92 EXPECT_EQ(NULL, realpath(NULL, buffer)); 93 EXPECT_EQ(EINVAL, errno); 94 95 // Test relative paths. 96 EXPECT_EQ(0, chdir("/tmp")); 97 98 EXPECT_STREQ("/", realpath("..", buffer)); 99 EXPECT_STREQ("/tmp", realpath(".", buffer)); 100 EXPECT_STREQ("/tmp", realpath("./", buffer)); 101 EXPECT_STREQ("/tmp", realpath("bar/..", buffer)); 102 EXPECT_STREQ("/tmp", realpath("bar/../../tmp", buffer)); 103 EXPECT_STREQ("/tmp", realpath(".///", buffer)); 104 EXPECT_STREQ("/tmp/bar", realpath("bar", buffer)); 105 106 // Test when resolved_path is allocated. 107 char* allocated = realpath("/tmp", NULL); 108 EXPECT_STREQ("/tmp", allocated); 109 free(allocated); 110 } 111 112 #endif // defined(__native_client__) || defined(STANDALONE) 113