Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 
     19 #include <errno.h>
     20 #include <fcntl.h>
     21 
     22 #include "TemporaryFile.h"
     23 
     24 TEST(fcntl, fcntl_smoke) {
     25   int fd = open("/proc/version", O_RDONLY);
     26   ASSERT_TRUE(fd != -1);
     27 
     28   int flags = fcntl(fd, F_GETFD);
     29   ASSERT_TRUE(flags != -1);
     30   ASSERT_EQ(0, flags & FD_CLOEXEC);
     31 
     32   int rc = fcntl(fd, F_SETFD, FD_CLOEXEC);
     33   ASSERT_EQ(0, rc);
     34 
     35   flags = fcntl(fd, F_GETFD);
     36   ASSERT_TRUE(flags != -1);
     37   ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC);
     38 
     39   close(fd);
     40 }
     41 
     42 TEST(fcntl, open_open64) {
     43   int fd;
     44 
     45   fd = open("/proc/version", O_RDONLY);
     46   ASSERT_TRUE(fd != -1);
     47   close(fd);
     48 
     49   fd = open64("/proc/version", O_RDONLY);
     50   ASSERT_TRUE(fd != -1);
     51   close(fd);
     52 }
     53 
     54 TEST(fcntl, openat_openat64) {
     55   int fd;
     56 
     57   fd = openat(AT_FDCWD, "/proc/version", O_RDONLY);
     58   ASSERT_TRUE(fd != -1);
     59   close(fd);
     60 
     61   fd = openat64(AT_FDCWD, "/proc/version", O_RDONLY);
     62   ASSERT_TRUE(fd != -1);
     63   close(fd);
     64 }
     65 
     66 TEST(fcntl, creat_creat64) {
     67   ASSERT_EQ(-1, creat("", 0666));
     68   ASSERT_EQ(ENOENT, errno);
     69   ASSERT_EQ(-1, creat64("", 0666));
     70   ASSERT_EQ(ENOENT, errno);
     71 }
     72 
     73 TEST(fcntl, posix_fadvise) {
     74   TemporaryFile tf;
     75   errno = 0;
     76 
     77   EXPECT_EQ(EBADF, posix_fadvise(-1, 0, 0, POSIX_FADV_NORMAL));
     78   EXPECT_EQ(0, errno);
     79 
     80   EXPECT_EQ(EBADF, posix_fadvise64(-1, 0, 0, POSIX_FADV_NORMAL));
     81   EXPECT_EQ(0, errno);
     82 
     83   EXPECT_EQ(EINVAL, posix_fadvise(tf.fd, 0, 0, -1));
     84   EXPECT_EQ(0, errno);
     85 
     86   EXPECT_EQ(EINVAL, posix_fadvise64(tf.fd, 0, 0, -1));
     87   EXPECT_EQ(0, errno);
     88 
     89   EXPECT_EQ(0, posix_fadvise(tf.fd, 0, 0, POSIX_FADV_NORMAL));
     90   EXPECT_EQ(0, posix_fadvise64(tf.fd, 0, 0, POSIX_FADV_NORMAL));
     91 }
     92 
     93 TEST(fcntl, fallocate_EINVAL) {
     94   TemporaryFile tf;
     95 
     96   // fallocate/fallocate64 set errno.
     97   // posix_fallocate/posix_fallocate64 return an errno value.
     98 
     99   errno = 0;
    100   ASSERT_EQ(-1, fallocate(tf.fd, 0, 0, -1));
    101   ASSERT_EQ(EINVAL, errno);
    102 
    103   errno = 0;
    104   ASSERT_EQ(-1, fallocate64(tf.fd, 0, 0, -1));
    105   ASSERT_EQ(EINVAL, errno);
    106 
    107   errno = 0;
    108   ASSERT_EQ(EINVAL, posix_fallocate(tf.fd, 0, -1));
    109   ASSERT_EQ(0, errno);
    110 
    111   errno = 0;
    112   ASSERT_EQ(EINVAL, posix_fallocate64(tf.fd, 0, -1));
    113   ASSERT_EQ(0, errno);
    114 }
    115 
    116 TEST(fcntl, fallocate) {
    117   TemporaryFile tf;
    118   struct stat sb;
    119   ASSERT_EQ(0, fstat(tf.fd, &sb));
    120   ASSERT_EQ(0, sb.st_size);
    121 
    122 #if defined(__BIONIC__)
    123   ASSERT_EQ(0, fallocate(tf.fd, 0, 0, 1));
    124   ASSERT_EQ(0, fstat(tf.fd, &sb));
    125   ASSERT_EQ(1, sb.st_size);
    126 
    127   ASSERT_EQ(0, fallocate64(tf.fd, 0, 0, 2));
    128   ASSERT_EQ(0, fstat(tf.fd, &sb));
    129   ASSERT_EQ(2, sb.st_size);
    130 #endif
    131 
    132   ASSERT_EQ(0, posix_fallocate(tf.fd, 0, 3));
    133   ASSERT_EQ(0, fstat(tf.fd, &sb));
    134   ASSERT_EQ(3, sb.st_size);
    135 
    136   ASSERT_EQ(0, posix_fallocate64(tf.fd, 0, 4));
    137   ASSERT_EQ(0, fstat(tf.fd, &sb));
    138   ASSERT_EQ(4, sb.st_size);
    139 }
    140 
    141 TEST(fcntl, f_getlk64) {
    142   int fd = open64("/proc/version", O_RDONLY);
    143   ASSERT_TRUE(fd != -1);
    144 
    145   struct flock64 check_lock;
    146   check_lock.l_type = F_WRLCK;
    147   check_lock.l_start = 0;
    148   check_lock.l_whence = SEEK_SET;
    149   check_lock.l_len = 0;
    150 
    151   int rc = fcntl(fd, F_GETLK64, &check_lock);
    152   ASSERT_EQ(0, rc);
    153 
    154   close(fd);
    155 }
    156 
    157 TEST(fcntl, splice) {
    158   int pipe_fds[2];
    159   ASSERT_EQ(0, pipe(pipe_fds));
    160 
    161   int in = open("/proc/cpuinfo", O_RDONLY);
    162   ASSERT_NE(in, -1);
    163 
    164   TemporaryFile tf;
    165 
    166   ssize_t bytes_read = splice(in, 0, pipe_fds[1], NULL, 8*1024, SPLICE_F_MORE | SPLICE_F_MOVE);
    167   ASSERT_NE(bytes_read, -1);
    168 
    169   ssize_t bytes_written = splice(pipe_fds[0], NULL, tf.fd, 0, bytes_read, SPLICE_F_MORE | SPLICE_F_MOVE);
    170   ASSERT_EQ(bytes_read, bytes_written);
    171 
    172   close(pipe_fds[0]);
    173   close(pipe_fds[1]);
    174   close(in);
    175 }
    176 
    177 TEST(fcntl, vmsplice) {
    178   int pipe_fds[2];
    179   ASSERT_EQ(0, pipe(pipe_fds));
    180 
    181   iovec v[2];
    182   v[0].iov_base = const_cast<char*>("hello ");
    183   v[0].iov_len = 6;
    184   v[1].iov_base = const_cast<char*>("world\n");
    185   v[1].iov_len = 6;
    186   ssize_t bytes_written = vmsplice(pipe_fds[1], v, sizeof(v)/sizeof(iovec), 0);
    187   ASSERT_EQ(v[0].iov_len + v[1].iov_len, static_cast<size_t>(bytes_written));
    188   close(pipe_fds[1]);
    189 
    190   char buf[BUFSIZ];
    191   FILE* fp = fdopen(pipe_fds[0], "r");
    192   ASSERT_TRUE(fp != NULL);
    193   ASSERT_TRUE(fgets(buf, sizeof(buf), fp) != NULL);
    194   fclose(fp);
    195   ASSERT_STREQ("hello world\n", buf);
    196 }
    197 
    198 TEST(fcntl, tee) {
    199   char expected[256];
    200   FILE* expected_fp = fopen("/proc/version", "r");
    201   ASSERT_TRUE(expected_fp != NULL);
    202   ASSERT_TRUE(fgets(expected, sizeof(expected), expected_fp) != NULL);
    203   fclose(expected_fp);
    204 
    205   int pipe1[2];
    206   ASSERT_EQ(0, pipe(pipe1));
    207 
    208   int pipe2[2];
    209   ASSERT_EQ(0, pipe(pipe2));
    210 
    211   int in = open("/proc/version", O_RDONLY);
    212   ASSERT_NE(in, -1);
    213 
    214   // Write /proc/version into pipe1.
    215   ssize_t bytes_read = splice(in, 0, pipe1[1], NULL, 8*1024, SPLICE_F_MORE | SPLICE_F_MOVE);
    216   ASSERT_NE(bytes_read, -1);
    217   close(pipe1[1]);
    218 
    219   // Tee /proc/version from pipe1 into pipe2.
    220   ssize_t bytes_teed = tee(pipe1[0], pipe2[1], SIZE_MAX, 0);
    221   ASSERT_EQ(bytes_read, bytes_teed);
    222   close(pipe2[1]);
    223 
    224   // The out fds of both pipe1 and pipe2 should now contain /proc/version.
    225   char buf1[BUFSIZ];
    226   FILE* fp1 = fdopen(pipe1[0], "r");
    227   ASSERT_TRUE(fp1 != NULL);
    228   ASSERT_TRUE(fgets(buf1, sizeof(buf1), fp1) != NULL);
    229   fclose(fp1);
    230 
    231   char buf2[BUFSIZ];
    232   FILE* fp2 = fdopen(pipe2[0], "r");
    233   ASSERT_TRUE(fp2 != NULL);
    234   ASSERT_TRUE(fgets(buf2, sizeof(buf2), fp2) != NULL);
    235   fclose(fp2);
    236 
    237   ASSERT_STREQ(expected, buf1);
    238   ASSERT_STREQ(expected, buf2);
    239 }
    240