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 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