| 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..2d8291ce40fe1d32d6a161465866f8b5f92a2367
|
| --- /dev/null
|
| +++ b/tests/nonsfi/file_descriptor_test.cc
|
| @@ -0,0 +1,171 @@
|
| +/*
|
| + * 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"
|
| +
|
| +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";
|
| +
|
| + // Create a test file under the |test_directory|.
|
| + {
|
| + char test_path[PATH_MAX];
|
| + snprintf(test_path, PATH_MAX, "%s/%s", test_directory, test_file_name);
|
| + FILE *fp = fopen(test_path, "w");
|
| + ASSERT_NE(fp, NULL);
|
| + fputs(test_file_content, fp);
|
| + fclose(fp);
|
| + }
|
| +
|
| + 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];
|
| + size_t len = 0;
|
| + while (true) {
|
| + ssize_t rc = read(fd, buf + len, kBufLen - len);
|
| + ASSERT_GE(rc, 0);
|
| + if (rc == 0)
|
| + break; // EOF.
|
| + len += rc;
|
| + }
|
| + ASSERT_EQ(len, sizeof(test_file_content) - 1);
|
| + ASSERT_EQ(memcmp(buf, test_file_content, len), 0);
|
| +
|
| + // Open for the non-directory fd.
|
| + 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 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_pipe2() {
|
| + puts("test for pipe2()");
|
| +
|
| + int fds[2];
|
| + int rc = pipe2(fds, O_NONBLOCK);
|
| + ASSERT_EQ(rc, 0);
|
| +
|
| + // Make sure O_NOBLOCK works.
|
| + const int kBufSize = 80;
|
| + char buf[kBufSize];
|
| + rc = read(fds[0], buf, kBufSize);
|
| + ASSERT_EQ(rc, -1);
|
| + ASSERT_EQ(errno, EAGAIN);
|
| + errno = 0;
|
| +
|
| + rc = close(fds[0]);
|
| + ASSERT_EQ(rc, 0);
|
| + rc = close(fds[1]);
|
| + ASSERT_EQ(rc, 0);
|
| +}
|
| +
|
| +void test_fstatat(const char *test_directory) {
|
| + puts("test for pipe2()");
|
| + 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);
|
| +
|
| + // Create an empty file.
|
| + {
|
| + FILE *fp = fopen(test_path, "w");
|
| + 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 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];
|
| + test_openat(test_directory);
|
| + test_pipe2();
|
| + test_fstatat(test_directory);
|
| +
|
| + puts("PASSED");
|
| + return 0;
|
| +}
|
|
|