1 /* 2 * Copyright (c) International Business Machines Corp., 2001 3 * 07/2001 Ported by Wayne Boyer 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 Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 /* 20 * fstat() should return value 0 on success and the stat structure elements 21 * should be filled with specified 'file' information. 22 */ 23 #include <stdio.h> 24 #include <sys/types.h> 25 #include <fcntl.h> 26 #include <sys/stat.h> 27 #include <errno.h> 28 #include <string.h> 29 #include <signal.h> 30 #include <pwd.h> 31 32 #include "test.h" 33 #include "safe_macros.h" 34 35 #define FILE_MODE 0644 36 #define TESTFILE "testfile" 37 #define FILE_SIZE 1024 38 #define BUF_SIZE 256 39 #define MASK 0777 40 41 char *TCID = "fstat02"; 42 int TST_TOTAL = 1; 43 static uid_t user_id; 44 static gid_t group_id; 45 static int fildes; 46 47 static void setup(void); 48 static void cleanup(void); 49 50 static void verify(void) 51 { 52 struct stat stat_buf; 53 int fail = 0; 54 55 TEST(fstat(fildes, &stat_buf)); 56 57 if (TEST_RETURN == -1) { 58 tst_resm(TFAIL | TTERRNO, "fstat(%s) failed", TESTFILE); 59 return; 60 } 61 62 if (stat_buf.st_uid != user_id) { 63 tst_resm(TINFO, "stat_buf.st_uid = %i expected %i", 64 stat_buf.st_uid, user_id); 65 fail++; 66 } 67 68 if (stat_buf.st_gid != group_id) { 69 tst_resm(TINFO, "stat_buf.st_gid = %i expected %i", 70 stat_buf.st_gid, group_id); 71 fail++; 72 } 73 74 if (stat_buf.st_size != FILE_SIZE) { 75 tst_resm(TINFO, "stat_buf.st_size = %zu expected %i", 76 stat_buf.st_size, FILE_SIZE); 77 fail++; 78 } 79 80 if ((stat_buf.st_mode & MASK) != FILE_MODE) { 81 tst_resm(TINFO, "stat_buf.st_mode = %o expected %o", 82 (stat_buf.st_mode & MASK), FILE_MODE); 83 fail++; 84 } 85 86 if (fail) { 87 tst_resm(TFAIL, "functionality of fstat incorrect"); 88 return; 89 } 90 91 tst_resm(TPASS, "functionality of fstat correct"); 92 } 93 94 int main(int ac, char **av) 95 { 96 int lc; 97 98 tst_parse_opts(ac, av, NULL, NULL); 99 100 setup(); 101 102 for (lc = 0; TEST_LOOPING(lc); lc++) 103 verify(); 104 105 cleanup(); 106 tst_exit(); 107 } 108 109 static void setup(void) 110 { 111 struct passwd *ltpuser; 112 char tst_buff[BUF_SIZE]; 113 int wbytes; 114 int write_len = 0; 115 116 tst_require_root(); 117 118 tst_sig(NOFORK, DEF_HANDLER, cleanup); 119 120 ltpuser = SAFE_GETPWNAM(NULL, "nobody"); 121 SAFE_SETUID(NULL, ltpuser->pw_uid); 122 123 TEST_PAUSE; 124 125 tst_tmpdir(); 126 127 umask(022); 128 129 fildes = SAFE_OPEN(tst_rmdir, TESTFILE, O_WRONLY | O_CREAT, FILE_MODE); 130 131 /* Fill the test buffer with the known data */ 132 memset(tst_buff, 'a', BUF_SIZE - 1); 133 134 /* Write to the file 1k data from the buffer */ 135 while (write_len < FILE_SIZE) { 136 if ((wbytes = write(fildes, tst_buff, sizeof(tst_buff))) <= 0) 137 tst_brkm(TBROK | TERRNO, cleanup, "write failed"); 138 else 139 write_len += wbytes; 140 } 141 142 user_id = getuid(); 143 group_id = getgid(); 144 } 145 146 static void cleanup(void) 147 { 148 if (close(fildes) == -1) 149 tst_resm(TWARN | TERRNO, "close failed"); 150 151 tst_rmdir(); 152 } 153