Chromium Code Reviews| Index: tests/nonsfi/file_descriptor_test.cc |
| diff --git a/tests/nonsfi/file_descriptor_test.cc b/tests/nonsfi/file_descriptor_test.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..582990e42eb280e03f4807476162a4fb64ff15d2 |
| --- /dev/null |
| +++ b/tests/nonsfi/file_descriptor_test.cc |
| @@ -0,0 +1,195 @@ |
| +/* |
| + * Copyright 2014 The Native Client Authors. All rights reserved. |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include <errno.h> |
| +#include <fcntl.h> |
| +#include <limits.h> |
| +#include <stdio.h> |
| +#include <string.h> |
| +#include <sys/stat.h> |
| +#include <unistd.h> |
| + |
| +#include "native_client/src/include/nacl_assert.h" |
| + |
| +static ssize_t read_from_fd(int fd, char* buf, size_t buf_len) { |
|
Mark Seaborn
2014/12/08 22:09:03
Use " *" spacing
hidehiko
2014/12/09 08:38:49
Acknowledged.
|
| + size_t len = 0; |
| + while (len < buf_len) { |
| + ssize_t rc = read(fd, buf + len, buf_len - len); |
| + if (rc < 0) |
| + return -1; |
| + if (rc == 0) |
| + break; // EOF. |
| + len += rc; |
| + } |
| + return len; |
| +} |
| + |
| +void test_openat(const char *test_directory) { |
| + puts("test for openat()"); |
| + const char test_file_name[] = "test_openat_file.txt"; |
| + const char test_file_content[] = "Hello, World.\n"; |
| + |
| + char test_path[PATH_MAX]; |
| + snprintf(test_path, PATH_MAX, "%s/%s", test_directory, test_file_name); |
|
Mark Seaborn
2014/12/08 22:09:03
How about using std::string instead?
hidehiko
2014/12/09 08:38:49
Done.
|
| + |
| + // Create a test file under the |test_directory|. |
| + { |
| + FILE *fp = fopen(test_path, "w"); |
| + ASSERT_NE(fp, NULL); |
| + fputs(test_file_content, fp); |
| + fclose(fp); |
|
Mark Seaborn
2014/12/08 22:09:03
Nit: check for error
hidehiko
2014/12/09 08:38:49
Done.
|
| + } |
| + |
| + int dirfd = open(test_directory, O_RDONLY | O_DIRECTORY); |
| + ASSERT_GE(dirfd, 0); |
| + |
| + int fd = openat(dirfd, test_file_name, O_RDONLY); |
| + ASSERT_GE(fd, 0); |
| + |
| + // Read the file content. |
| + const int kBufLen = 80; |
| + char buf[kBufLen]; |
| + ssize_t len = read_from_fd(fd, buf, kBufLen); |
| + ASSERT_EQ(len, sizeof(test_file_content) - 1); |
| + ASSERT_EQ(memcmp(buf, test_file_content, len), 0); |
| + |
| + // Open for the non-directory fd. |
|
Mark Seaborn
2014/12/08 22:09:02
Grammar nit: remove "for"
hidehiko
2014/12/09 08:38:49
Done.
|
| + int fd2 = openat(fd, test_file_name, O_RDONLY); |
| + ASSERT_EQ(fd2, -1); |
| + ASSERT_EQ(errno, ENOTDIR); |
| + errno = 0; |
| + |
| + int rc = close(fd); |
| + ASSERT_EQ(rc, 0); |
| + |
| + // Test for AT_FDCWD. |
| + { |
| + char original_directory[PATH_MAX]; |
| + ASSERT_NE(getcwd(original_directory, PATH_MAX), NULL); |
| + ASSERT_EQ(chdir(test_directory), 0); |
| + |
| + fd = openat(AT_FDCWD, test_file_name, O_RDONLY); |
| + ASSERT_GE(fd, 0); |
| + len = read_from_fd(fd, buf, kBufLen); |
| + ASSERT_EQ(len, sizeof(test_file_content) - 1); |
| + ASSERT_EQ(memcmp(buf, test_file_content, len), 0); |
| + |
| + ASSERT_EQ(chdir(original_directory), 0); |
| + } |
| + |
| + // Test for non-existing file. |
| + fd = openat(dirfd, "non-existing-file", O_RDONLY); |
| + ASSERT_EQ(fd, -1); |
| + ASSERT_EQ(errno, ENOENT); |
| + errno = 0; |
| + |
| + rc = close(dirfd); |
| + ASSERT_EQ(rc, 0); |
| + |
| + // Test for invalid directory fd. |
| + fd = openat(-1, test_file_name, O_RDONLY); |
| + ASSERT_EQ(fd, -1); |
| + ASSERT_EQ(errno, EBADF); |
| +} |
| + |
| +void test_fstatat(const char *test_directory) { |
| + puts("test for fstatat()"); |
| + const char test_file_name[] = "test_fstatat_file.txt"; |
| + char test_path[PATH_MAX]; |
| + snprintf(test_path, PATH_MAX, "%s/%s", test_directory, test_file_name); |
|
Mark Seaborn
2014/12/08 22:09:03
Use std::string?
hidehiko
2014/12/09 08:38:49
Done.
|
| + |
| + // Create an empty file. |
| + { |
| + FILE *fp = fopen(test_path, "w"); |
|
Mark Seaborn
2014/12/08 22:09:03
Check for error
hidehiko
2014/12/09 08:38:49
Done.
|
| + fclose(fp); |
| + } |
| + |
| + struct stat buf; |
| + struct stat buf2; |
| + int rc = stat(test_path, &buf); |
| + ASSERT_EQ(rc, 0); |
| + int dirfd = open(test_directory, O_RDONLY | O_DIRECTORY); |
| + ASSERT_GE(dirfd, 0); |
| + // Currently, no |flag| is defined. So, pass 0. |
| + rc = fstatat(dirfd, test_file_name, &buf2, 0); |
| + ASSERT_EQ(rc, 0); |
| + ASSERT_EQ(buf.st_dev, buf2.st_dev); |
| + ASSERT_EQ(buf.st_mode, buf2.st_mode); |
| + ASSERT_EQ(buf.st_nlink, buf2.st_nlink); |
| + ASSERT_EQ(buf.st_uid, buf2.st_uid); |
| + ASSERT_EQ(buf.st_gid, buf2.st_gid); |
| + ASSERT_EQ(buf.st_rdev, buf2.st_rdev); |
| + ASSERT_EQ(buf.st_size, buf2.st_size); |
| + ASSERT_EQ(buf.st_blksize, buf2.st_blksize); |
| + ASSERT_EQ(buf.st_blocks, buf2.st_blocks); |
| + ASSERT_EQ(buf.st_atime, buf2.st_atime); |
| + ASSERT_EQ(buf.st_mtime, buf2.st_mtime); |
| + ASSERT_EQ(buf.st_ctime, buf2.st_ctime); |
| + |
| + // Test for AT_FDCWD. |
| + { |
| + char original_directory[PATH_MAX]; |
| + ASSERT_NE(getcwd(original_directory, PATH_MAX), NULL); |
| + ASSERT_EQ(chdir(test_directory), 0); |
| + |
| + rc = fstatat(AT_FDCWD, test_file_name, &buf2, 0); |
| + ASSERT_EQ(rc, 0); |
| + ASSERT_EQ(buf.st_dev, buf2.st_dev); |
| + ASSERT_EQ(buf.st_mode, buf2.st_mode); |
| + ASSERT_EQ(buf.st_nlink, buf2.st_nlink); |
| + ASSERT_EQ(buf.st_uid, buf2.st_uid); |
| + ASSERT_EQ(buf.st_gid, buf2.st_gid); |
| + ASSERT_EQ(buf.st_rdev, buf2.st_rdev); |
| + ASSERT_EQ(buf.st_size, buf2.st_size); |
| + ASSERT_EQ(buf.st_blksize, buf2.st_blksize); |
| + ASSERT_EQ(buf.st_blocks, buf2.st_blocks); |
| + ASSERT_EQ(buf.st_atime, buf2.st_atime); |
| + ASSERT_EQ(buf.st_mtime, buf2.st_mtime); |
| + ASSERT_EQ(buf.st_ctime, buf2.st_ctime); |
| + |
| + ASSERT_EQ(chdir(original_directory), 0); |
| + } |
| + |
| + // Test for non-existing file. |
| + rc = fstatat(dirfd, "not-existing-file", &buf, 0); |
| + ASSERT_EQ(rc, -1); |
| + ASSERT_EQ(errno, ENOENT); |
| + errno = 0; |
| + |
| + rc = close(dirfd); |
| + ASSERT_EQ(rc, 0); |
| + |
| + // With invalid file descriptor. |
| + rc = fstatat(-1, test_file_name, &buf2, 0); |
| + ASSERT_EQ(rc, -1); |
| + ASSERT_EQ(errno, EBADF); |
| + errno = 0; |
| + |
| + // Test with non-directory file descriptor. |
| + int fd = open(test_path, O_RDONLY); |
| + ASSERT_GE(fd, 0); |
| + rc = fstatat(fd, test_file_name, &buf2, 0); |
| + ASSERT_EQ(rc, -1); |
| + ASSERT_EQ(errno, ENOTDIR); |
| + errno = 0; |
| + |
| + rc = close(fd); |
| + ASSERT_EQ(rc, 0); |
| +} |
| + |
| +int main(int argc, char *argv[]) { |
| + if (argc != 2) { |
| + printf("Please specify the test directory name.\n"); |
| + exit(-1); |
| + } |
| + |
| + const char* test_directory = argv[1]; |
|
Mark Seaborn
2014/12/08 22:09:03
Use " *" spacing
hidehiko
2014/12/09 08:38:49
Done.
|
| + test_openat(test_directory); |
| + test_fstatat(test_directory); |
| + |
| + puts("PASSED"); |
| + return 0; |
| +} |