Home | History | Annotate | Download | only in write
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2001
      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  * NAME
     22  *	write03.c
     23  *
     24  * DESCRIPTION
     25  *	Testcase to check that write(2) doesn't corrupt a file when it fails
     26  *
     27  * ALGORITHM
     28  *	Create a file for writing, write 100 bytes to it. Then make write(2)
     29  *	fail with some erroneous parameter, close the fd. Then reopen the
     30  *	file in RDONLY mode, and read the contents of the file. Compare the
     31  *	buffers, to see whether they are same.
     32  *
     33  * USAGE:  <for command-line>
     34  *      write03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
     35  *      where,  -c n : Run n copies concurrently.
     36  *              -e   : Turn on errno logging.
     37  *              -i n : Execute test n times.
     38  *              -I x : Execute test for x seconds.
     39  *              -P x : Pause for x seconds between iterations.
     40  *              -t   : Turn on syscall timing.
     41  *
     42  * History
     43  *	07/2001 John George
     44  *		-Ported
     45  *
     46  * Restrictions
     47  *	NONE
     48  */
     49 
     50 #include <unistd.h>
     51 #include <string.h>
     52 #include <fcntl.h>
     53 #include <errno.h>
     54 #include "test.h"
     55 #include <sys/mman.h>
     56 
     57 char *TCID = "write03";
     58 int TST_TOTAL = 1;
     59 
     60 char *bad_addr = 0;
     61 
     62 void setup(void);
     63 void cleanup(void);
     64 
     65 char filename[100];
     66 
     67 #if !defined(UCLINUX)
     68 
     69 int main(int argc, char **argv)
     70 {
     71 	int lc;
     72 
     73 	char wbuf[BUFSIZ], rbuf[BUFSIZ];
     74 	int fd;
     75 
     76 	tst_parse_opts(argc, argv, NULL, NULL);
     77 
     78 	/* global setup */
     79 	setup();
     80 
     81 	/* The following loop checks looping state if -i option given */
     82 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     83 
     84 		/* reset tst_count in case we are looping */
     85 		tst_count = 0;
     86 
     87 //block1:
     88 		tst_resm(TINFO, "Enter Block 1: test to check if write "
     89 			 "corrupts the file when write fails");
     90 
     91 		fd = creat(filename, 0644);
     92 		if (fd < 0) {
     93 			tst_resm(TBROK, "creating a new file failed");
     94 			cleanup();
     95 		}
     96 
     97 		(void)memset(wbuf, '0', 100);
     98 
     99 		if (write(fd, wbuf, 100) == -1) {
    100 			tst_resm(TFAIL, "failed to write to %s", filename);
    101 			cleanup();
    102 		}
    103 
    104 		if (write(fd, bad_addr, 100) != -1) {
    105 			tst_resm(TFAIL, "write(2) failed to fail");
    106 			cleanup();
    107 		}
    108 		close(fd);
    109 
    110 		if ((fd = open(filename, O_RDONLY)) == -1) {
    111 			tst_resm(TBROK, "open(2) failed, errno: %d", errno);
    112 			cleanup();
    113 		}
    114 
    115 		if (read(fd, rbuf, 100) == -1) {
    116 			tst_resm(TBROK, "read(2) failed, errno: %d", errno);
    117 			cleanup();
    118 		}
    119 
    120 		if (memcmp(wbuf, rbuf, 100) == 0) {
    121 			tst_resm(TPASS, "failure of write(2) didnot corrupt "
    122 				 "the file");
    123 		} else {
    124 			tst_resm(TFAIL, "failure of write(2) corrupted the "
    125 				 "file");
    126 		}
    127 		tst_resm(TINFO, "Exit block 1");
    128 		close(fd);
    129 	}
    130 	cleanup();
    131 	tst_exit();
    132 }
    133 
    134 #else
    135 
    136 int main(void)
    137 {
    138 	tst_resm(TINFO, "test is not available on uClinux");
    139 	tst_exit();
    140 }
    141 
    142 #endif /* if !defined(UCLINUX) */
    143 
    144 /*
    145  * setup() - performs all ONE TIME setup for this test
    146  */
    147 void setup(void)
    148 {
    149 
    150 	tst_sig(FORK, DEF_HANDLER, cleanup);
    151 
    152 	/* Pause if that option was specified
    153 	 * TEST_PAUSE contains the code to fork the test with the -i option.
    154 	 * You want to make sure you do this before you create your temporary
    155 	 * directory.
    156 	 */
    157 	TEST_PAUSE;
    158 
    159 	/* Create a unique temporary directory and chdir() to it. */
    160 	tst_tmpdir();
    161 
    162 	sprintf(filename, "./write03.%d", getpid());
    163 
    164 	bad_addr = mmap(0, 1, PROT_NONE,
    165 			MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, 0, 0);
    166 	if (bad_addr == MAP_FAILED) {
    167 		printf("mmap failed\n");
    168 	}
    169 
    170 }
    171 
    172 /*
    173  * cleanup() - performs all ONE TIME cleanup for this test at
    174  *		completion or premature exit
    175  */
    176 void cleanup(void)
    177 {
    178 
    179 	unlink(filename);
    180 	tst_rmdir();
    181 
    182 }
    183