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
verify(void)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 = %li expected %i",
76 (long)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
main(int ac,char ** av)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
setup(void)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
cleanup(void)146 static void cleanup(void)
147 {
148 if (close(fildes) == -1)
149 tst_resm(TWARN | TERRNO, "close failed");
150
151 tst_rmdir();
152 }
153