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 * Test Name: utime03 22 * 23 * Test Description: 24 * Verify that the system call utime() successfully sets the modification 25 * and access times of a file to the current time, under the following 26 * constraints, 27 * - The times argument is null. 28 * - The user ID of the process is not "root". 29 * - The file is not owned by the user ID of the process. 30 * - The user ID of the process has write access to the file. 31 * 32 * Expected Result: 33 * utime succeeds returning zero and sets the access and modificatio 34 * times of the file to the current time. 35 * 36 * Algorithm: 37 * Setup: 38 * Setup signal handling. 39 * Create temporary directory. 40 * Pause for SIGUSR1 if option specified. 41 * 42 * Test: 43 * Loop if the proper options are given. 44 * Execute system call 45 * Check return code, if system call failed (return=-1) 46 * Log the errno and Issue a FAIL message. 47 * Otherwise, 48 * Verify the Functionality of system call 49 * if successful, 50 * Issue Functionality-Pass message. 51 * Otherwise, 52 * Issue Functionality-Fail message. 53 * Cleanup: 54 * Print errno log and/or timing stats if options given 55 * Delete the temporary directory created. 56 * 57 * Usage: <for command-line> 58 * utime03 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t] 59 * where, -c n : Run n copies concurrently. 60 * -e : Turn on errno logging. 61 * -f : Turn off functionality Testing. 62 * -i n : Execute test n times. 63 * -I x : Execute test for x seconds. 64 * -P x : Pause for x seconds between iterations. 65 * -t : Turn on syscall timing. 66 * 67 * History 68 * 07/2001 John George 69 * -Ported 70 * 71 * Restrictions: 72 * This test should be run by root only. 73 * nobody and bin must be valid users. 74 * 75 */ 76 77 #include <errno.h> 78 #include <fcntl.h> 79 #include <pwd.h> 80 #include <signal.h> 81 #include <stdio.h> 82 #include <stdlib.h> 83 #include <string.h> 84 #include <unistd.h> 85 #include <utime.h> 86 #include <sys/wait.h> 87 #include <sys/stat.h> 88 #include <sys/types.h> 89 #include <time.h> 90 91 #include "test.h" 92 #include "safe_macros.h" 93 94 #define TEMP_FILE "tmp_file" 95 #define FILE_MODE S_IRWXU | S_IRGRP | S_IWGRP| S_IROTH | S_IWOTH 96 #define LTPUSER1 "nobody" 97 #define LTPUSER2 "bin" 98 99 char *TCID = "utime03"; 100 int TST_TOTAL = 1; 101 time_t curr_time; /* current time in seconds */ 102 103 struct passwd *ltpuser; /* password struct for ltpusers */ 104 uid_t user_uid; /* user id of ltpuser */ 105 gid_t group_gid; /* group id of ltpuser */ 106 int status; 107 108 void setup(); /* Main setup function of test */ 109 void cleanup(); /* cleanup function for the test */ 110 111 int main(int ac, char **av) 112 { 113 struct stat stat_buf; /* struct buffer to hold file info. */ 114 int lc; 115 long type; 116 time_t modf_time, access_time; 117 time_t pres_time; /* file modification/access/present time */ 118 pid_t pid; 119 120 tst_parse_opts(ac, av, NULL, NULL); 121 122 setup(); 123 124 switch ((type = tst_fs_type(cleanup, "."))) { 125 case TST_NFS_MAGIC: 126 if (tst_kvercmp(2, 6, 18) < 0) 127 tst_brkm(TCONF, cleanup, "Cannot do utime on a file" 128 " on %s filesystem before 2.6.18", 129 tst_fs_type_name(type)); 130 break; 131 case TST_V9FS_MAGIC: 132 tst_brkm(TCONF, cleanup, 133 "Cannot do utime on a file on %s filesystem", 134 tst_fs_type_name(type)); 135 break; 136 } 137 138 pid = FORK_OR_VFORK(); 139 140 if (pid == -1) { 141 tst_brkm(TBROK, cleanup, "fork() failed"); 142 } else if (pid == 0) { 143 if ((ltpuser = getpwnam(LTPUSER1)) == NULL) { 144 tst_brkm(TBROK, cleanup, "%s not found in /etc/passwd", 145 LTPUSER1); 146 } 147 148 /* get uid/gid of user accordingly */ 149 user_uid = ltpuser->pw_uid; 150 151 seteuid(user_uid); 152 153 for (lc = 0; TEST_LOOPING(lc); lc++) { 154 155 tst_count = 0; 156 157 /* 158 * Invoke utime(2) to set TEMP_FILE access and 159 * modification times to the current time. 160 */ 161 TEST(utime(TEMP_FILE, NULL)); 162 163 if (TEST_RETURN == -1) { 164 tst_resm(TFAIL|TTERRNO, 165 "utime(%s) failed", TEMP_FILE); 166 } else { 167 /* 168 * Sleep for a second so that mod time 169 * and access times will be different 170 * from the current time. 171 */ 172 sleep(2); 173 174 /* 175 * Get the current time now, after 176 * calling utime(2) 177 */ 178 pres_time = time(NULL); 179 180 /* 181 * Get the modification and access 182 * times of temporary file using 183 * stat(2). 184 */ 185 SAFE_STAT(cleanup, TEMP_FILE, &stat_buf); 186 modf_time = stat_buf.st_mtime; 187 access_time = stat_buf.st_atime; 188 189 /* Now do the actual verification */ 190 if (modf_time <= curr_time || 191 modf_time >= pres_time || 192 access_time <= curr_time || 193 access_time >= pres_time) { 194 tst_resm(TFAIL, "%s access and " 195 "modification times " 196 "not set", TEMP_FILE); 197 } else { 198 tst_resm(TPASS, "Functionality " 199 "of utime(%s, NULL) " 200 "successful", 201 TEMP_FILE); 202 } 203 } 204 tst_count++; /* incr. TEST_LOOP counter */ 205 } 206 } else { 207 waitpid(pid, &status, 0); 208 _exit(0); /* 209 * Exit here and let the child clean up. 210 * This allows the errno information set 211 * by the TEST_ERROR_LOG macro and the 212 * PASS/FAIL status to be preserved for 213 * use during cleanup. 214 */ 215 } 216 217 cleanup(); 218 tst_exit(); 219 220 } 221 222 /* 223 * void 224 * setup() - performs all ONE TIME setup for this test. 225 * Create a temporary directory and change directory to it. 226 * Create a test file under temporary directory and close it 227 * Change the ownership of testfile to that of "bin" user. 228 * Record the current time. 229 */ 230 void setup(void) 231 { 232 int fildes; /* file handle for temp file */ 233 char *tmpd = NULL; 234 235 tst_require_root(); 236 237 tst_sig(FORK, DEF_HANDLER, cleanup); 238 239 /* Pause if that option was specified 240 * TEST_PAUSE contains the code to fork the test with the -i option. 241 * You want to make sure you do this before you create your temporary 242 * directory. 243 */ 244 TEST_PAUSE; 245 246 tst_tmpdir(); 247 248 /* get the name of the temporary directory */ 249 tmpd = SAFE_GETCWD(NULL, tmpd, 0); 250 251 /* Creat a temporary file under above directory */ 252 fildes = SAFE_CREAT(cleanup, TEMP_FILE, FILE_MODE); 253 254 /* Close the temporary file created */ 255 SAFE_CLOSE(cleanup, fildes); 256 257 /* 258 * Make sure that specified Mode permissions set as 259 * umask value may be different. 260 */ 261 SAFE_CHMOD(cleanup, TEMP_FILE, FILE_MODE); 262 SAFE_CHMOD(cleanup, tmpd, 0711); 263 264 ltpuser = SAFE_GETPWNAM(cleanup, LTPUSER2); 265 266 /* get uid/gid of user accordingly */ 267 user_uid = ltpuser->pw_uid; 268 group_gid = ltpuser->pw_gid; 269 270 /* 271 * Change the ownership of test directory/file specified by 272 * pathname to that of user_uid and group_gid. 273 */ 274 SAFE_CHOWN(cleanup, TEMP_FILE, user_uid, group_gid); 275 276 /* Get the current time */ 277 curr_time = time(NULL); 278 279 /* 280 * Sleep for a second so that mod time and access times will be 281 * different from the current time 282 */ 283 sleep(2); /* sleep(1) on IA64 sometimes sleeps < 1 sec!! */ 284 285 } 286 287 /* 288 * void 289 * cleanup() - performs all ONE TIME cleanup for this test at 290 * completion or premature exit. 291 * Remove the test directory and testfile created in the setup. 292 */ 293 void cleanup(void) 294 { 295 seteuid(0); 296 297 tst_rmdir(); 298 299 } 300