int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ /* parse standard options */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; //test1: l_seek(fd, CHUNK * 11, 0); if (readv(fd, (rd_iovec + 0), 0) == -1) { tst_resm(TFAIL, "readv() failed with unexpected errno " "%d", errno); } else { tst_resm(TPASS, "readv read 0 io vectors"); } //test2: l_seek(fd, CHUNK * 12, 0); if (readv(fd, (rd_iovec + 1), 4) != CHUNK) { tst_resm(TFAIL, "readv failed reading %d bytes, " "followed by two NULL vectors", CHUNK); } else { tst_resm(TPASS, "readv passed reading %d bytes, " "followed by two NULL vectors", CHUNK); } } close(fd); cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; //test1: if (readv(fd[0], rd_iovec, 1) < 0) { if (errno != EINVAL) { tst_resm(TFAIL, "readv() set an illegal errno:" " expected: EINVAL, got %d", errno); } else { tst_resm(TPASS, "got EINVAL"); } } else { tst_resm(TFAIL, "Error: readv returned a positive " "value"); } //test2: l_seek(fd[0], CHUNK * 6, 0); if (readv(fd[0], (rd_iovec + 6), 3) < 0) { if (errno != EFAULT) { tst_resm(TFAIL, "expected errno = EFAULT, " "got %d", errno); } else { tst_resm(TPASS, "got EFAULT"); } if (memcmp((buf_list[0] + CHUNK * 6), (buf_list[1] + CHUNK * 6), CHUNK * 3) != 0) { tst_resm(TFAIL, "Error: readv() partially " "overlaid buf[2]"); } } else { tst_resm(TFAIL, "Error: readv returned a positive " "value"); } //test3: if (readv(fd[1], (rd_iovec + 9), 1) < 0) { if (errno != EBADF) { tst_resm(TFAIL, "expected errno = EBADF, " "got %d", errno); } else { tst_resm(TPASS, "got EBADF"); } } else { tst_resm(TFAIL, "Error: readv returned a positive " "value"); } //test4: l_seek(fd[0], CHUNK * 10, 0); if (readv(fd[0], (rd_iovec + 10), -1) < 0) { if (errno != EINVAL) { tst_resm(TFAIL, "expected errno = EINVAL, " "got %d", errno); } else { tst_resm(TPASS, "got EINVAL"); } } else { tst_resm(TFAIL, "Error: readv returned a positive " "value"); } } close(fd[0]); close(fd[1]); cleanup(); tst_exit(); }
int main(int argc, char **argv) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int nbytes; /* parse standard options */ if ((msg = parse_opts(argc, argv, (option_t *)NULL, NULL)) != (char *) NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); tst_exit(); /*NOTREACHED*/ } setup(); /* set "tstdir", and "testfile" vars */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; buf_list[0] = buf1; buf_list[1] = buf2; /* Fill the buf_list[0] and buf_list[1] with 0 zeros */ memset(buf_list[0], 0, K_1); memset(buf_list[1], 0, K_1); fd[1] = -1; /* Invalid file descriptor */ if (signal(SIGTERM, sighandler) == SIG_ERR) { perror("signal"); tst_resm(TFAIL, "signal() SIGTERM FAILED"); cleanup(); /*NOTREACHED*/ } if (signal(SIGPIPE, sighandler) == SIG_ERR) { perror("signal"); tst_resm(TFAIL, "signal() SIGPIPE FAILED"); cleanup(); /*NOTREACHED*/ } if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) { tst_resm(TFAIL, "open(2) failed: fname = %s, " "errno = %d", f_name, errno); cleanup(); /*NOTREACHED*/ } else { l_seek(fd[0], K_1, 0); if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) { tst_resm(TFAIL, "write(2) failed: nbytes " "= %d, errno = %d", nbytes, errno); cleanup(); /*NOTREACHED*/ } } if (close(fd[0]) < 0) { tst_resm(TFAIL, "close failed: errno = %d", errno); cleanup(); /*NOTREACHED*/ } if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) { tst_resm(TFAIL, "open failed: fname = %s, errno = %d", f_name, errno); cleanup(); /*NOTREACHED*/ } //block1: /* * In this block we are trying to call writev() with invalid * vector to be written in a sparse file. This will return * EFAULT. At the same time, check should be made whether * the scheduled write() with valid data at 8k th offset is * done correctly or not. */ tst_resm(TINFO, "Enter block 1"); fail = 0; l_seek(fd[0], 0, 0); TEST(writev(fd[0], wr_iovec, 2)); if (TEST_RETURN < 0) { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == EFAULT) { tst_resm(TINFO, "Received EFAULT as expected"); } else if (TEST_ERRNO != EFAULT) { tst_resm(TFAIL, "Expected EFAULT, got %d", TEST_ERRNO); fail = 1; } l_seek(fd[0], K_1, 0); if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != CHUNK) { tst_resm(TFAIL, "Expected nbytes = 64, got " "%d", nbytes); fail = 1; } else { if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) { tst_resm(TFAIL, "Error: writev() " "over wrote %s", f_name); fail = 1; } } } else { tst_resm(TFAIL, "Error writev returned a positive " "value"); fail = 1; } if (fail) { tst_resm(TINFO, "block 1 FAILED"); } else { tst_resm(TINFO, "block 1 PASSED"); } tst_resm(TINFO, "Exit block 1"); } cleanup(); return(0); }
/* * setup() - performs all ONE TIME setup for this test. * * Initialize/allocate read/write buffers. * Create a temporary directory and a file under it and * write know data at different offset positions. */ void setup() { int nwrite = 0; /* no. of bytes written by pwrite() */ tst_sig(FORK, DEF_HANDLER, cleanup); TEST_PAUSE; /* Allocate/Initialize the read/write buffer with know data */ init_buffers(); tst_tmpdir(); /* Creat a temporary file used for mapping */ if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) { tst_brkm(TBROK, cleanup, "open() on %s failed, errno=%d : %s", TEMPFILE, errno, strerror(errno)); } /* pwrite() K1 of data (0's) at offset 0 of temporary file */ if ((nwrite = pwrite(fildes, write_buf[0], K1, 0)) != K1) { tst_brkm(TBROK, cleanup, "pwrite() failed to write on %s, " "errno=%d : %s", TEMPFILE, errno, strerror(errno)); } /* We should still be at offset 0. */ l_seek(fildes, 0, SEEK_CUR, 0); /* Now, lseek() to a non K boundary, just to be different. */ l_seek(fildes, K1 / 2, SEEK_SET, K1 / 2); /* Again, pwrite() K1 of data (2's) at offset K2 of temporary file */ if ((nwrite = pwrite(fildes, write_buf[2], K1, K2)) != K1) { tst_brkm(TBROK, cleanup, "pwrite() failed to write at %d off. " "on %s, errno=%d : %s", K2, TEMPFILE, errno, strerror(errno)); } /* We should still be at our non K boundary. */ l_seek(fildes, 0, SEEK_CUR, K1 / 2); /* lseek() to an offset of K3. */ l_seek(fildes, K3, SEEK_SET, K3); /* * Using write(), write of K1 of data (3's) which should take * place at an offset of K3, moving the file pointer to K4. */ if ((nwrite = write(fildes, write_buf[3], K1)) != K1) { tst_brkm(TBROK, cleanup, "write() failed: nwrite=%d, errno=%d " ": %s", nwrite, errno, strerror(errno)); } /* We should be at offset K4. */ l_seek(fildes, 0, SEEK_CUR, K4); /* Again, pwrite() K1 of data (1's) at offset K1. */ if ((nwrite = pwrite(fildes, write_buf[1], K1, K1)) != K1) { tst_brkm(TBROK, cleanup, "pwrite() failed to write at %d off. " "on %s, errno=%d : %s", K1, TEMPFILE, errno, strerror(errno)); } }
int main(int ac, char **av) { int lc; char *msg; int nread; /* no. of bytes read by pread() */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { /* Reset tst_count in case we are looping */ tst_count = 0; /* * Call pread() of K1 data (should be 2's) at offset K2. */ nread = pread(fildes, read_buf[2], K1, K2); /* Check for the return value of pread() */ if (nread != K1) { tst_brkm(TFAIL, cleanup, "pread() at off. K2 failed: " "nread=%d, error:%d", nread, errno); } /* * We should still be at offset K4, * which we were at the end of block 0. */ l_seek(fildes, 0, SEEK_CUR, K4); /* Now lseek() to offset 0. */ l_seek(fildes, 0, SEEK_SET, 0); /* pread() K1 of data (should be 3's) at offset K3. */ nread = pread(fildes, read_buf[3], K1, K3); if (nread != K1) { tst_brkm(TFAIL, cleanup, "pread() at off. K3 failed: " "nread=%d, error:%d", nread, errno); } /* We should still be at offset 0. */ l_seek(fildes, 0, SEEK_CUR, 0); /* * Do a normal read() of K1 data (should be 0's) * which should take place at offset 0 and move the * file pointer to an offset of K1. */ if ((nread = read(fildes, read_buf[0], K1)) != K1) { tst_brkm(TFAIL, cleanup, "read() at off. 0 failed: " "nread=%d, errno=%d", nread, errno); } /* We should now be at an offset of K1. */ l_seek(fildes, 0, SEEK_CUR, K1); /* pread() of K1 data (should be 1's) at offset K1. */ nread = pread(fildes, read_buf[1], K1, K1); if (nread != K1) { tst_brkm(TFAIL, cleanup, "pread() at off. K1 failed: " "nread=%d, error:%d", nread, errno); } /* We should still be at offset K1. */ l_seek(fildes, 0, SEEK_CUR, K1); /* * Perform functional verification if test * executed without (-f) option. */ if (STD_FUNCTIONAL_TEST) { /* * Compare the read buffer data read * with the data written to write buffer * in the setup. */ compare_bufers(); } else { tst_resm(TPASS, "calls to pread() succeeded"); } /* reset our location to offset K4 in case we are looping */ l_seek(fildes, K4, SEEK_SET, K4); } cleanup(); tst_exit(); tst_exit(); }
int main(int argc, char **argv) { int nbytes, ret; int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ /* parse standard options */ if ((msg = parse_opts(argc, argv, (option_t *) NULL, NULL)) != (char *)NULL) { tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); /*NOTREACHED*/ } /* set "tstdir", and "testfile" vars */ setup(); /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; buf_list[0] = buf1; buf_list[1] = buf2; buf_list[2] = buf3; buf_list[3] = (char *)NULL; fd[1] = -1; /* Invalid file descriptor */ if (signal(SIGTERM, sighandler) == SIG_ERR) { perror("signal: SIGTERM"); cleanup(); /*NOTREACHED*/ } if (signal(SIGPIPE, sighandler) == SIG_ERR) { perror("signal: SIGPIPE"); cleanup(); /*NOTREACHED*/ } init_buffs(buf_list); if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) { tst_resm(TFAIL, "open failed: fname = %s, errno = %d", f_name, errno); cleanup(); /*NOTREACHED*/ } else if ((nbytes = write(fd[0], buf_list[2], K_1)) != K_1) { tst_resm(TFAIL, "write failed: nbytes = %d, " "errno = %d", nbytes, errno); cleanup(); /*NOTREACHED*/ } if (close(fd[0]) < 0) { tst_resm(TFAIL, "close failed: errno: %d", errno); cleanup(); /*NOTREACHED*/ } if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) { tst_resm(TFAIL, "open failed: fname = %s, errno = %d", f_name, errno); cleanup(); /*NOTREACHED*/ } //block1: /* given vector length -1, writev() return EINVAL. */ tst_resm(TINFO, "Enter Block 1"); fail = 0; TEST(writev(fd[0], wr_iovec, 1)); if (TEST_RETURN < 0) { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == EINVAL) { tst_resm(TINFO, "Received EINVAL as expected"); } else { tst_resm(TFAIL, "Expected errno = EINVAL, " "got %d", TEST_ERRNO); fail = 1; } } else { tst_resm(TFAIL, "writev() failed to fail"); fail = 1; } if (fail) { tst_resm(TINFO, "block 1 FAILED"); } else { tst_resm(TINFO, "block 1 PASSED"); } tst_resm(TINFO, "Exit block 1"); //block2: /* This testcases doesn't look like what it intent to do * 1. it is not using the wr_iovec initialized * 2. read() and following message is not consistent */ tst_resm(TINFO, "Enter block 2"); fail = 0; if (l_seek(fd[0], CHUNK * 6, 0) < 0) { TEST_ERROR_LOG(errno); tst_resm(TBROK, "block2: 1st lseek failed"); fail = 1; } if ((ret = writev(fd[0], (wr_iovec + 6), 3)) == CHUNK) { if (l_seek(fd[0], CHUNK * 6, 0) < 0) { TEST_ERROR_LOG(errno); tst_resm(TFAIL, "block2: 2nd lseek failed"); fail = 1; } if ((nbytes = read(fd[0], buf_list[0], CHUNK)) != CHUNK) { perror("read error"); tst_resm(TFAIL, "expected nbytes = 1024, " "got = %d", nbytes); fail = 1; } else if (memcmp((buf_list[0] + CHUNK * 6), (buf_list[2] + CHUNK * 6), CHUNK) != 0) { tst_resm(TFAIL, "Error: writev() over " "wrote %s", f_name); fail = 1; } } else { tst_resm(TFAIL, "writev() failed unexpectedly"); fail = 1; } if (fail) { tst_resm(TINFO, "block 2 FAILED"); } else { tst_resm(TINFO, "block 2 PASSED"); } tst_resm(TINFO, "Exit block 2"); //block3: /* given 1 bad vector buffer with good ones, writev() success */ tst_resm(TINFO, "Enter block 3"); fail = 0; if (lseek(fd[0], CHUNK * 6, 0) < 0) { TEST_ERROR_LOG(errno); tst_resm(TFAIL, "block3: 1st lseek failed"); fail = 1; } if ((nbytes = writev(fd[0], (wr_iovec + 6), 3)) < 0) { TEST_ERROR_LOG(errno); if (errno == EFAULT) { tst_resm(TFAIL, "Got EFAULT"); fail = 1; } } if (l_seek(fd[0], 0, 0) < 0) { TEST_ERROR_LOG(errno); tst_resm(TFAIL, "block3: 2nd lseek failed"); fail = 1; } if ((nbytes = read(fd[0], buf_list[0], K_1)) != K_1) { perror("read error"); tst_resm(TFAIL, "expected nbytes = 1024, got = %d", nbytes); fail = 1; } else if (memcmp((buf_list[0] + CHUNK * 6), (buf_list[2] + CHUNK * 6), CHUNK * 3) != 0) { tst_resm(TFAIL, "Error: writev() over wrote %s", f_name); fail = 1; } if (fail) { tst_resm(TINFO, "block 3 FAILED"); } else { tst_resm(TINFO, "block 3 PASSED"); } tst_resm(TINFO, "Exit block 3"); //block4: /* given bad file discriptor, writev() return EBADF. */ tst_resm(TINFO, "Enter block 4"); fail = 0; TEST(writev(fd[1], (wr_iovec + 9), 1)); if (TEST_RETURN < 0) { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == EBADF) { tst_resm(TINFO, "Received EBADF as expected"); } else { tst_resm(TFAIL, "expected errno = EBADF, " "got %d", TEST_ERRNO); fail = 1; } } else { tst_resm(TFAIL, "Error: writev() returned a " "positive value"); fail = 1; } if (fail) { tst_resm(TINFO, "block 4 FAILED"); } else { tst_resm(TINFO, "block 4 PASSED"); } tst_resm(TINFO, "Exit block 4"); //block5: /* given invalid vector count, writev() return EINVAL */ tst_resm(TINFO, "Enter block 5"); fail = 0; TEST(writev(fd[0], (wr_iovec + 10), -1)); if (TEST_RETURN < 0) { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == EINVAL) { tst_resm(TINFO, "Received EINVAL as expected"); } else { tst_resm(TFAIL, "expected errno = EINVAL, " "got %d", TEST_ERRNO); fail = 1; } } else { tst_resm(TFAIL, "Error: writev() returned a " "positive value"); fail = 1; } if (fail) { tst_resm(TINFO, "block 5 FAILED"); } else { tst_resm(TINFO, "block 5 PASSED"); } tst_resm(TINFO, "Exit block 5"); //block6: /* given no buffer vector, writev() success */ tst_resm(TINFO, "Enter block 6"); fail = 0; TEST(writev(fd[0], (wr_iovec + 11), 0)); if (TEST_RETURN < 0) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "writev() failed with unexpected errno " "%d", TEST_ERRNO); fail = 1; } else { tst_resm(TPASS, "writev() wrote 0 iovectors"); } if (fail) { tst_resm(TINFO, "block 6 FAILED"); } else { tst_resm(TINFO, "block 6 PASSED"); } tst_resm(TINFO, "Exit block 6"); //block7: /* given 4 vectors, 2 are NULL, 1 with 0 length and 1 with fixed length, * writev() success writing fixed length. */ tst_resm(TINFO, "Enter block 7"); fail = 0; l_seek(fd[0], CHUNK * 12, 0); if ((ret = writev(fd[0], (wr_iovec + 12), 4)) != CHUNK) { tst_resm(TFAIL, "writev() failed writing %d bytes, " "followed by two NULL vectors", CHUNK); fail = 1; } else { tst_resm(TPASS, "writev passed writing %d bytes, " "followed by two NULL vectors", CHUNK); } if (fail) { tst_resm(TINFO, "block 7 FAILED"); } else { tst_resm(TINFO, "block 7 PASSED"); } tst_resm(TINFO, "Exit block 7"); //block8: /* try to write to a closed pipe, writev() return EPIPE. */ tst_resm(TINFO, "Enter block 8"); fail = 0; if (pipe(pfd) < 0) { TEST_ERROR_LOG(errno); perror("pipe"); tst_resm(TFAIL, "pipe failed: errno = %d", errno); fail = 1; } else { if (close(pfd[0]) < 0) { TEST_ERROR_LOG(errno); perror("close"); tst_resm(TFAIL, "close failed: errno = %d", errno); fail = 1; } else if ((writev(pfd[1], (wr_iovec + 12), 1) < 0) && in_sighandler) { TEST_ERROR_LOG(errno); if (errno == EPIPE) { tst_resm(TINFO, "Received EPIPE as " "expected"); } else { tst_resm(TFAIL, "expected errno = " "EPIPE, got %d", errno); fail = 1; } } else { tst_resm(TFAIL, "Error: writev() returned a " "positive value"); fail = 1; } } if (fail) { tst_resm(TINFO, "block 8 FAILED"); } else { tst_resm(TINFO, "block 8 PASSED"); } tst_resm(TINFO, "Exit block 8"); } close(fd[0]); close(fd[1]); cleanup(); /*NOTREACHED*/ return 0; }
int main(int argc, char **argv) { int lc; int nbytes; tst_parse_opts(argc, argv, NULL, NULL); setup(); /* set "tstdir", and "testfile" vars */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset tst_count in case we are looping */ tst_count = 0; buf_list[0] = buf1; buf_list[1] = buf2; buf_list[2] = buf3; buf_list[3] = NULL; fd[1] = -1; /* Invalid file descriptor */ if (signal(SIGTERM, sighandler) == SIG_ERR) { perror("signal"); tst_resm(TFAIL, "signal() SIGTERM FAILED"); cleanup(); } if (signal(SIGPIPE, sighandler) == SIG_ERR) { perror("signal"); tst_resm(TFAIL, "signal() SIGPIPE FAILED"); cleanup(); } memset(buf_list[0], 0, K_1); memset(buf_list[1], 0, K_1); if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) { tst_resm(TFAIL, "open(2) failed: fname = %s, " "errno = %d", f_name, errno); cleanup(); } else { if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) { tst_resm(TFAIL, "write(2) failed: nbytes " "= %d, errno = %d", nbytes, errno); cleanup(); } } if (close(fd[0]) < 0) { tst_resm(TFAIL, "close failed: errno = %d", errno); cleanup(); } if ((fd[0] = open(f_name, O_RDWR, 0666)) < 0) { tst_brkm(TFAIL, cleanup, "open failed: fname = %s, errno = %d", f_name, errno); } //block1: tst_resm(TINFO, "Enter block 1"); fail = 0; /* * In this block we are trying to call writev() with * partially valid data. This should return the valid number * of bytes written in the vector. If it returns EFAULT, it * is an error. And after returning the number of valid * bytes written, the check should be made to verify the * contents of the first valid write() scheduled. */ if (writev(fd[0], wr_iovec, 3) < 0) { fail = 1; if (errno == EFAULT) { tst_resm(TFAIL, "Got error EFAULT"); } else { tst_resm(TFAIL, "Received unexpected error: %d", errno); } } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) { tst_resm(TFAIL, "writev overwrote the file"); fail = 1; } } if (fail) { tst_resm(TINFO, "block 1 FAILED"); } else { tst_resm(TINFO, "block 1 PASSED"); } tst_resm(TINFO, "Exit block 1"); //block2: tst_resm(TINFO, "Enter block 2"); fail = 0; /* * In this block we are trying to over write the contents by * calling writev() with partially valid data. It should * return the valid number of bytes written but not EFAULT. * Also the check should be made whether the initial write() * scheduled is done correctly or not. */ l_seek(fd[0], 0, 0); if (writev(fd[0], wr_iovec, 3) < 0) { fail = 1; if (errno == EFAULT) { tst_resm(TFAIL, "Got error EFAULT"); } else { tst_resm(TFAIL, "Received unexpected error: %d", errno); } } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) { tst_resm(TFAIL, "writev overwrote the file"); fail = 1; } } if (fail) { tst_resm(TINFO, "block 2 FAILED"); } else { tst_resm(TINFO, "block 2 PASSED"); } tst_resm(TINFO, "Exit block 2"); //block3: tst_resm(TINFO, "Enter block 3"); fail = 0; /* * In this block, we are trying to call writev() by going to * some end position of the file. Here writev() is called * with partially valid data, and this will return the * number of valid bytes written and not EFAULT. Also, the * check should be made whether the inital write() that is * scheduled with valid data is done correctly. */ l_seek(fd[0], 8192, 0); if (writev(fd[0], wr_iovec, 3) < 0) { fail = 1; if (errno == EFAULT) { tst_resm(TFAIL, "Got error EFAULT"); } else { tst_resm(TFAIL, "Received unexpected error: %d", errno); } } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) { tst_resm(TFAIL, "writev overwrote the file"); fail = 1; } } if (fail) { tst_resm(TINFO, "block 3 FAILED"); } else { tst_resm(TINFO, "block 3 PASSED"); } tst_resm(TINFO, "Exit block 3"); } close(fd[0]); close(fd[1]); cleanup(); tst_exit(); }
int main(int ac, char *av[]) { int fd; int nbytes; char *wbuf[NBUFS]; struct stat statbuf; int lc; strcpy(name, DATA_FILE); sprintf(fname, "%s.%d", name, getpid()); tst_parse_opts(ac, av, NULL, NULL); tst_tmpdir(); for (lc = 0; TEST_LOOPING(lc); lc++) { init_buffers(wbuf); local_flag = PASSED; if ((fd = open(fname, O_RDWR | O_CREAT, 0666)) < 0) { tst_resm(TBROK, "open failed: fname = %s, errno = %d", fname, errno); cleanup(); } /* * pwrite() K1 of data (0's) at offset 0. */ if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) { tst_resm(TFAIL, "pwrite at 0 failed: nbytes=%d, errno=%d", nbytes, errno); cleanup(); } /* * We should still be at offset 0. */ l_seek(fd, 0, SEEK_CUR, 0); /* * lseek() to a non K boundary, just to be different. */ l_seek(fd, K1 / 2, SEEK_SET, K1 / 2); /* * pwrite() K1 of data (2's) at offset K2. */ if ((nbytes = pwrite(fd, wbuf[2], K1, K2)) != K1) { tst_resm(TFAIL, "pwrite at K2 failed: nbytes=%d, errno=%d", nbytes, errno); cleanup(); } /* * We should still be at our non K boundary. */ l_seek(fd, 0, SEEK_CUR, K1 / 2); /* * lseek() to an offset of K3. */ l_seek(fd, K3, SEEK_SET, K3); /* * This time use a normal write() of K1 of data (3's) which should * take place at an offset of K3, moving the file pointer to K4. */ if ((nbytes = write(fd, wbuf[3], K1)) != K1) { tst_resm(TFAIL, "write failed: nbytes=%d, errno=%d", nbytes, errno); cleanup(); } /* * We should be at offset K4. */ l_seek(fd, 0, SEEK_CUR, K4); /* * pwrite() K1 of data (1's) at offset K1. */ if ((nbytes = pwrite(fd, wbuf[1], K1, K1)) != K1) { tst_resm(TFAIL, "pwrite failed: nbytes=%d, errno=%d", nbytes, errno); cleanup(); } /*--------------------------------------------------------------*/ /* * Now test that O_APPEND takes precedence over any * offset specified by pwrite(), but that the file * pointer remains unchanged. First, close then reopen * the file and ensure it is already K4 in length and * set the file pointer to it's midpoint, K2. */ close(fd); if ((fd = open(fname, O_RDWR | O_APPEND, 0666)) < 0) { tst_resm(TBROK, "open failed: fname = %s, errno = %d", fname, errno); cleanup(); } if (fstat(fd, &statbuf) == -1) { tst_resm(TFAIL, "fstat failed: errno = %d", errno); cleanup(); } if (statbuf.st_size != K4) { tst_resm(TFAIL, "file size is %ld != K4", statbuf.st_size); cleanup(); } l_seek(fd, K2, SEEK_SET, K2); /* * Finally, pwrite() some K1 of data at offset 0. * What we should end up with is: * -The file pointer should still be at K2. * -The data should have been written to the end * of the file (O_APPEND) and should be K5 in size. */ if ((nbytes = pwrite(fd, wbuf[0], K1, 0)) != K1) { tst_resm(TFAIL, "pwrite at 0 failed: nbytes=%d, errno=%d", nbytes, errno); } l_seek(fd, 0, SEEK_CUR, K2); if (fstat(fd, &statbuf) == -1) { tst_resm(TFAIL, "fstat failed: errno = %d", errno); } if (statbuf.st_size != K5) { tst_resm(TFAIL, "file size is %ld != K4", statbuf.st_size); } tst_resm(TPASS, "O_APPEND test passed."); /*------------------------------------------------------------------------*/ close(fd); unlink(fname); } /* end for */ cleanup(); tst_exit(); }
int main(int argc, char **argv) { int lc; char *msg; int nbytes; if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; buf_list[0] = buf1; buf_list[1] = buf2; buf_list[2] = buf3; buf_list[3] = NULL; fd[1] = -1; /* Invalid file descriptor */ if (signal(SIGTERM, sighandler) == SIG_ERR) tst_brkm(TBROK | TERRNO, cleanup, "signal(SIGTERM, ..) failed"); if (signal(SIGPIPE, sighandler) == SIG_ERR) tst_brkm(TBROK | TERRNO, cleanup, "signal(SIGPIPE, ..) failed"); memset(buf_list[0], 0, K_1); memset(buf_list[1], 0, K_1); if ((fd[0] = open(f_name, O_WRONLY | O_CREAT, 0666)) == -1) tst_brkm(TBROK | TERRNO, cleanup, "open(.., O_WRONLY|O_CREAT, ..) failed"); else if ((nbytes = write(fd[0], buf_list[1], K_1)) != K_1) tst_brkm(TFAIL | TERRNO, cleanup, "write failed"); if (close(fd[0]) < 0) tst_brkm(TBROK | TERRNO, cleanup, "close failed"); if ((fd[0] = open(f_name, O_RDWR, 0666)) == -1) tst_brkm(TBROK | TERRNO, cleanup, "open(.., O_RDWR, ..) failed"); //block1: tst_resm(TINFO, "Enter block 1"); /* * In this block we are trying to call writev() with * partially valid data. This should return the valid number * of bytes written in the vector. If it returns EFAULT, it * is an error. And after returning the number of valid * bytes written, the check should be made to verify the * contents of the first valid write() scheduled. */ if (writev(fd[0], wr_iovec, 3) == -1) { if (errno == EFAULT) tst_resm(TFAIL, "Got EFAULT"); } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) tst_resm(TFAIL, "writev overwrote the file"); } tst_resm(TINFO, "Exit block 1"); //block2: tst_resm(TINFO, "Enter block 2"); /* * In this block we are trying to over write the contents by * calling writev() with partially valid data. It should * return the valid number of bytes written but not EFAULT. * Also the check should be made whether the initial write() * scheduled is done correctly or not. */ l_seek(fd[0], 0, 0); if (writev(fd[0], wr_iovec, 3) == -1) { if (errno == EFAULT) tst_resm(TFAIL, "Got EFAULT"); } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) tst_resm(TFAIL, "writev overwrote the file"); } tst_resm(TINFO, "Exit block 2"); //block3: tst_resm(TINFO, "Enter block 3"); /* * In this block, we are trying to call writev() by going to * some end position of the file. Here writev() is called * with partially valid data, and this will return the * number of valid bytes written and not EFAULT. Also, the * check should be made whether the inital write() that is * scheduled with valid data is done correctly done or not. */ l_seek(fd[0], 8192, 0); if (writev(fd[0], wr_iovec, 3) == -1) { TEST_ERROR_LOG(errno); if (errno == EFAULT) tst_resm(TFAIL, "Got EFAULT"); } else { l_seek(fd[0], 0, 0); read(fd[0], buf_list[0], CHUNK); if (memcmp(buf_list[0], buf_list[1], CHUNK) != 0) { tst_resm(TFAIL, "writev overwrote the file"); } } tst_resm(TINFO, "Exit block 3"); } cleanup(); tst_exit(); }