Home | History | Annotate | Download | only in ftruncate
      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