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 #include <sys/syscall.h>
22 #include <sys/time.h>
23 
24 #include <android-base/file.h>
25 
26 #include "utils.h"
27 
28 // http://b/11383777
TEST(sys_time,utimes_nullptr)29 TEST(sys_time, utimes_nullptr) {
30   TemporaryFile tf;
31   ASSERT_EQ(0, utimes(tf.path, nullptr));
32 }
33 
TEST(sys_time,utimes_EINVAL)34 TEST(sys_time, utimes_EINVAL) {
35   TemporaryFile tf;
36 
37   timeval tv[2] = {};
38 
39   tv[0].tv_usec = -123;
40   ASSERT_EQ(-1, utimes(tf.path, tv));
41   ASSERT_ERRNO(EINVAL);
42   tv[0].tv_usec = 1234567;
43   ASSERT_EQ(-1, utimes(tf.path, tv));
44   ASSERT_ERRNO(EINVAL);
45 
46   tv[0].tv_usec = 0;
47 
48   tv[1].tv_usec = -123;
49   ASSERT_EQ(-1, utimes(tf.path, tv));
50   ASSERT_ERRNO(EINVAL);
51   tv[1].tv_usec = 1234567;
52   ASSERT_EQ(-1, utimes(tf.path, tv));
53   ASSERT_ERRNO(EINVAL);
54 }
55 
TEST(sys_time,futimes_nullptr)56 TEST(sys_time, futimes_nullptr) {
57   TemporaryFile tf;
58   ASSERT_EQ(0, futimes(tf.fd, nullptr));
59 }
60 
TEST(sys_time,futimes_EINVAL)61 TEST(sys_time, futimes_EINVAL) {
62   TemporaryFile tf;
63 
64   timeval tv[2] = {};
65 
66   tv[0].tv_usec = -123;
67   ASSERT_EQ(-1, futimes(tf.fd, tv));
68   ASSERT_ERRNO(EINVAL);
69   tv[0].tv_usec = 1234567;
70   ASSERT_EQ(-1, futimes(tf.fd, tv));
71   ASSERT_ERRNO(EINVAL);
72 
73   tv[0].tv_usec = 0;
74 
75   tv[1].tv_usec = -123;
76   ASSERT_EQ(-1, futimes(tf.fd, tv));
77   ASSERT_ERRNO(EINVAL);
78   tv[1].tv_usec = 1234567;
79   ASSERT_EQ(-1, futimes(tf.fd, tv));
80   ASSERT_ERRNO(EINVAL);
81 }
82 
TEST(sys_time,futimesat_nullptr)83 TEST(sys_time, futimesat_nullptr) {
84   TemporaryFile tf;
85   ASSERT_EQ(0, futimesat(AT_FDCWD, tf.path, nullptr));
86 }
87 
TEST(sys_time,futimesat_EINVAL)88 TEST(sys_time, futimesat_EINVAL) {
89   TemporaryFile tf;
90 
91   timeval tv[2] = {};
92 
93   tv[0].tv_usec = -123;
94   ASSERT_EQ(-1, futimesat(AT_FDCWD, tf.path, tv));
95   ASSERT_ERRNO(EINVAL);
96   tv[0].tv_usec = 1234567;
97   ASSERT_EQ(-1, futimesat(AT_FDCWD, tf.path, tv));
98   ASSERT_ERRNO(EINVAL);
99 
100   tv[0].tv_usec = 0;
101 
102   tv[1].tv_usec = -123;
103   ASSERT_EQ(-1, futimesat(AT_FDCWD, tf.path, tv));
104   ASSERT_ERRNO(EINVAL);
105   tv[1].tv_usec = 1234567;
106   ASSERT_EQ(-1, futimesat(AT_FDCWD, tf.path, tv));
107   ASSERT_ERRNO(EINVAL);
108 }
109 
TEST(sys_time,lutimes_nullptr)110 TEST(sys_time, lutimes_nullptr) {
111   TemporaryFile tf;
112   ASSERT_EQ(0, lutimes(tf.path, nullptr));
113 }
114 
TEST(sys_time,lutimes_EINVAL)115 TEST(sys_time, lutimes_EINVAL) {
116   TemporaryFile tf;
117 
118   timeval tv[2] = {};
119 
120   tv[0].tv_usec = -123;
121   ASSERT_EQ(-1, lutimes(tf.path, tv));
122   ASSERT_ERRNO(EINVAL);
123   tv[0].tv_usec = 1234567;
124   ASSERT_EQ(-1, lutimes(tf.path, tv));
125   ASSERT_ERRNO(EINVAL);
126 
127   tv[0].tv_usec = 0;
128 
129   tv[1].tv_usec = -123;
130   ASSERT_EQ(-1, lutimes(tf.path, tv));
131   ASSERT_ERRNO(EINVAL);
132   tv[1].tv_usec = 1234567;
133   ASSERT_EQ(-1, lutimes(tf.path, tv));
134   ASSERT_ERRNO(EINVAL);
135 }
136 
137 // Musl doesn't define __NR_gettimeofday on 32-bit architectures.
138 #if !defined(__NR_gettimeofday)
139 #define __NR_gettimeofday __NR_gettimeofday_time32
140 #endif
141 
TEST(sys_time,gettimeofday)142 TEST(sys_time, gettimeofday) {
143   // Try to ensure that our vdso gettimeofday is working.
144   timeval tv1;
145   ASSERT_EQ(0, gettimeofday(&tv1, nullptr));
146   timeval tv2;
147   ASSERT_EQ(0, syscall(__NR_gettimeofday, &tv2, nullptr));
148 
149   // What's the difference between the two?
150   tv2.tv_sec -= tv1.tv_sec;
151   tv2.tv_usec -= tv1.tv_usec;
152   if (tv2.tv_usec < 0) {
153     --tv2.tv_sec;
154     tv2.tv_usec += 1000000;
155   }
156 
157   // To try to avoid flakiness we'll accept answers within 10,000us (0.01s).
158   ASSERT_EQ(0, tv2.tv_sec);
159   ASSERT_LT(tv2.tv_usec, 10'000);
160 }
161