• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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