1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
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: ftruncate03
22 *
23 * Test Description:
24 * Verify that,
25 * 1) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
26 * socket is invalid.
27 * 2) ftruncate(2) returns -1 and sets errno to EINVAL if the specified
28 * file descriptor has an attempt to write, when open for read only.
29 * 3) ftruncate(2) returns -1 and sets errno to EBADF if the file descriptor
30 * of the specified file is not valid.
31 *
32 * Expected Result:
33 * ftruncate() should fail with return value -1 and set expected errno.
34 *
35 * HISTORY
36 * 02/2002 Written by Jay Huie
37 * 02/2002 Adapted for and included into the LTP by Robbie Williamson
38 *
39 * RESTRICTIONS:
40 * This test should be run by 'non-super-user' only.
41 *
42 */
43
44 #include <stdio.h>
45 #include <unistd.h>
46 #include <errno.h>
47 #include <string.h>
48 #include <inttypes.h>
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <fcntl.h>
52
53 #include "test.h"
54
55 #define TESTFILE "ftruncate03_tst_file"
56
57 TCID_DEFINE(ftruncate03);
58 int TST_TOTAL = 3;
59
main(void)60 int main(void)
61 {
62 int wjh_ret = -1, wjh_f = -1, count = 0;
63 //used for the 2nd test
64 //make str > trunc_size characters long
65 char str[] = "THIS IS JAYS TEST FILE DATA";
66 int trunc_size = 4;
67 int flag = O_RDONLY;
68
69 #ifdef DEBUG
70 printf("Starting test, possible errnos are; EBADF(%d) EINVAL(%d)\n",
71 EBADF, EINVAL);
72 printf("\t\tENOENT(%d) EACCES(%d) EPERM(%d)\n\n", ENOENT, EACCES,
73 EPERM);
74 #endif
75
76 tst_tmpdir();
77
78 //TEST1: ftruncate on a socket is not valid, should fail w/ EINVAL
79
80 #ifdef DEBUG
81 printf("Starting test1\n");
82 #endif
83 wjh_f = socket(PF_INET, SOCK_STREAM, 0);
84 wjh_ret = ftruncate(wjh_f, 1);
85 #ifdef DEBUG
86 printf("DEBUG: fd: %d ret: %d errno(%d) %s\n",
87 wjh_f, wjh_ret, errno, strerror(errno));
88 #endif
89 if (wjh_ret == -1 && errno == EINVAL) {
90 tst_resm(TPASS, "Test Passed");
91 } else {
92 tst_resm(TFAIL,
93 "ftruncate(socket)=%i (wanted -1), errno=%i (wanted EINVAL %i)",
94 wjh_ret, errno, EINVAL);
95 }
96 close(wjh_f);
97 errno = 0;
98 wjh_ret = 0;
99 wjh_f = -1;
100
101 //TEST2: ftruncate on fd not open for writing should be EINVAL
102
103 #ifdef DEBUG
104 printf("\nStarting test2\n");
105 #endif
106 //create a file and fill it so we can truncate it in ReadOnly mode
107 //delete it first, ignore if it doesn't exist
108 unlink(TESTFILE);
109 errno = 0;
110 wjh_f = open(TESTFILE, O_RDWR | O_CREAT, 0644);
111 if (wjh_f == -1) {
112 tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
113 TESTFILE);
114 }
115 while (count < strlen(str)) {
116 if ((count += write(wjh_f, str, strlen(str))) == -1) {
117 tst_resm(TFAIL | TERRNO, "write() failed");
118 close(wjh_f);
119 tst_rmdir();
120 tst_exit();
121 }
122 }
123 close(wjh_f);
124 errno = 0;
125
126 //Uncomment below if you want it to succeed, O_RDWR => success
127 // flag = O_RDWR;
128 #ifdef DEBUG
129 if (flag == O_RDWR) {
130 printf("\tLooks like it should succeed!\n");
131 }
132 #endif
133
134 wjh_f = open(TESTFILE, flag);
135 if (wjh_f == -1) {
136 tst_brkm(TFAIL | TERRNO, tst_rmdir, "open(%s) failed",
137 TESTFILE);
138 }
139 wjh_ret = ftruncate(wjh_f, trunc_size);
140 #ifdef DEBUG
141 printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
142 wjh_f, wjh_ret, errno, strerror(errno));
143 #endif
144 if ((flag == O_RDONLY) && (wjh_ret == -1) && (errno == EINVAL)) {
145 tst_resm(TPASS, "Test Passed");
146 } else if ((flag == O_RDWR)) {
147 if (wjh_ret == 0) {
148 tst_resm(TPASS, "Test Succeeded!");
149 } else {
150 tst_resm(TFAIL | TERRNO,
151 "ftruncate(%s) should have succeeded, but didn't! ret="
152 "%d (wanted 0)", TESTFILE, wjh_ret);
153 }
154 } else //flag was O_RDONLY but return codes wrong
155 {
156 tst_resm(TFAIL,
157 "ftruncate(rd_only_fd)=%i (wanted -1), errno=%i (wanted %i EINVAL)",
158 wjh_ret, errno, EINVAL);
159 }
160 close(wjh_f);
161 errno = 0;
162 wjh_ret = 0;
163 wjh_f = -1;
164
165 //TEST3: invalid socket descriptor should fail w/ EBADF
166
167 #ifdef DEBUG
168 printf("\nStarting test3\n");
169 #endif
170 wjh_f = -999999; //should be a bad file descriptor
171 wjh_ret = ftruncate(wjh_f, trunc_size);
172 #ifdef DEBUG
173 printf("DEBUG: fd: %d ret: %d @ errno(%d) %s\n",
174 wjh_f, wjh_ret, errno, strerror(errno));
175 #endif
176 if (wjh_ret != -1 || errno != EBADF) {
177 tst_resm(TFAIL | TERRNO,
178 "ftruncate(invalid_fd)=%d (wanted -1 and EBADF)",
179 wjh_ret);
180 } else {
181 tst_resm(TPASS, "Test Passed");
182 }
183
184 tst_rmdir();
185
186 //Done Testing
187 tst_exit();
188 }
189