1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * settimeofday02.c
23 *
24 * DESCRIPTION
25 * Testcase to check that settimeofday() sets errnos correctly.
26 *
27 * ALGORITHM
28 * Setup:
29 * Setup signal handling.
30 * Check that we are not root.
31 * Setup expected errnos.
32 * Pause for SIGUSER1 if option specified.
33 * Save the current time values.
34 * Loop if the proper options are given.
35 * Call settimeofday with an invalid "buf" address and verify that
36 * errno is set to EFAULT.
37 * Call settimeofday as a non-root user. Verify that the call fails
38 * and errno is set to EPERM.
39 * Cleanup:
40 * Print errno log and/or timing stats if options given.
41 *
42 * USAGE: <for command-line>
43 * settimeofday02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
44 * where, -c n : Run n copies concurrently.
45 * -e : Turn on errno logging.
46 * -i n : Execute test n times.
47 * -I x : Execute test for x seconds.
48 * -P x : Pause for x seconds between iterations.
49 * -t : Turn on syscall timing.
50 *
51 * History
52 * 07/2001 John George
53 * -Ported
54 *
55 * Restrictions
56 * Must not be run as root
57 */
58
59 #include <stdio.h>
60 #include <sys/time.h>
61 #include <errno.h>
62 #include "test.h"
63 #include <pwd.h>
64
65 #define VAL_SEC 100
66 #define VAL_MSEC 100
67
68 char *TCID = "settimeofday02";
69 int TST_TOTAL = 1;
70
71 struct timeval tp;
72 time_t save_tv_sec, save_tv_usec;
73
74 char nobody_uid[] = "nobody";
75 struct passwd *ltpuser;
76
77 void setup(void);
78 void cleanup(void);
79 void restore_time(void);
80
81 #if !defined(UCLINUX)
82
main(int argc,char ** argv)83 int main(int argc, char **argv)
84 {
85 int lc;
86
87 tst_parse_opts(argc, argv, NULL, NULL);
88
89 setup();
90
91 for (lc = 0; TEST_LOOPING(lc); lc++) {
92 /* reset tst_count in case we are looping */
93 tst_count = 0;
94
95 TEST(settimeofday((void *)-1, NULL));
96 if (TEST_RETURN != -1) {
97 tst_resm(TFAIL, "settimeofday(2) failed to FAIL");
98 restore_time();
99 } else {
100 if (TEST_ERRNO != EFAULT) {
101 tst_resm(TFAIL, "Expected EFAULT got %d",
102 TEST_ERRNO);
103 } else {
104 tst_resm(TPASS, "Received expected errno");
105 }
106 }
107
108 tp.tv_sec = VAL_SEC;
109 tp.tv_usec = VAL_MSEC;
110 TEST(settimeofday(&tp, NULL));
111 if (TEST_RETURN != -1) {
112 tst_resm(TFAIL, "settimeofday(2) failed to FAIL");
113 restore_time();
114 } else {
115 if (TEST_ERRNO != EPERM) {
116 tst_resm(TFAIL, "Expected EPERM got %d",
117 TEST_ERRNO);
118 } else {
119 tst_resm(TPASS, "Received expected errno");
120 }
121 }
122 }
123 cleanup();
124 tst_exit();
125
126 }
127
128 #else
129
main(void)130 int main(void)
131 {
132 tst_resm(TINFO, "test is not available on uClinux");
133 tst_exit();
134 }
135
136 #endif /* if !defined(UCLINUX) */
137
138 /*
139 * setup()
140 * performs all ONE TIME setup for this test
141 */
setup(void)142 void setup(void)
143 {
144 tst_require_root();
145
146 tst_sig(FORK, DEF_HANDLER, cleanup);
147
148 /* Switch to nobody user for correct error code collection */
149 ltpuser = getpwnam(nobody_uid);
150 if (setuid(ltpuser->pw_uid) == -1) {
151 tst_resm(TINFO, "setuid failed to "
152 "to set the effective uid to %d", ltpuser->pw_uid);
153 perror("setuid");
154 }
155
156 /* Pause if that option was specified
157 * TEST_PAUSE contains the code to fork the test with the -c option.
158 */
159 TEST_PAUSE;
160
161 /* Save the current time values */
162 if ((gettimeofday(&tp, (struct timezone *)&tp)) == -1) {
163 tst_brkm(TBROK, cleanup, "gettimeofday failed. "
164 "errno=%d", errno);
165 }
166 save_tv_sec = tp.tv_sec;
167 save_tv_usec = tp.tv_usec;
168 }
169
170 /*
171 * cleanup()
172 * performs all ONE TIME cleanup for this test at
173 * completion or premature exit
174 */
cleanup(void)175 void cleanup(void)
176 {
177
178 }
179
restore_time(void)180 void restore_time(void)
181 {
182 /* restore the original time values. */
183 tp.tv_sec = save_tv_sec;
184 tp.tv_usec = save_tv_usec;
185 if ((settimeofday(&tp, NULL)) == -1) {
186 tst_resm(TWARN, "FATAL COULD NOT RESET THE CLOCK");
187 tst_resm(TFAIL, "Error Setting Time, errno=%d", errno);
188 }
189 }
190