Home | History | Annotate | Download | only in pwritev
      1 /*
      2 * Copyright (c) 2015-2016 Fujitsu Ltd.
      3 * Author: Xiao Yang <yangx.jy (at) cn.fujitsu.com>
      4 *
      5 * This program is free software; you can redistribute it and/or modify it
      6 * under the terms of version 2 of the GNU General Public License as
      7 * published by the Free Software Foundation.
      8 *
      9 * This program is distributed in the hope that it would be useful, but
     10 * WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 *
     13 * You should have received a copy of the GNU General Public License
     14 * alone with this program.
     15 */
     16 
     17 /*
     18 * Test Name: pwritev02
     19 *
     20 * Description:
     21 * 1) pwritev(2) fails if iov_len is invalid.
     22 * 2) pwritev(2) fails if the vector count iovcnt is less than zero.
     23 * 3) pwritev(2) fails if offset is negative.
     24 * 4) pwritev(2) fails when attempts to write from a invalid address
     25 * 5) pwritev(2) fails if file descriptor is invalid.
     26 * 6) pwritev(2) fails if file descriptor is not open for writing.
     27 * 7) pwritev(2) fails if fd is associated with a pipe.
     28 *
     29 * Expected Result:
     30 * 1) pwritev(2) should return -1 and set errno to EINVAL.
     31 * 2) pwritev(2) should return -1 and set errno to EINVAL.
     32 * 3) pwritev(2) should return -1 and set errno to EINVAL.
     33 * 4) pwritev(2) should return -1 and set errno to EFAULT.
     34 * 5) pwritev(2) should return -1 and set errno to EBADF.
     35 * 6) pwritev(2) should return -1 and set errno to EBADF.
     36 * 7) pwritev(2) should return -1 and set errno to ESPIPE.
     37 */
     38 
     39 #include <sys/uio.h>
     40 #include <unistd.h>
     41 #include "tst_test.h"
     42 #include "pwritev.h"
     43 
     44 #define CHUNK           64
     45 
     46 static int fd1;
     47 static int fd2;
     48 static int fd3 = -1;
     49 static int fd4[2];
     50 
     51 static char buf[CHUNK];
     52 
     53 static struct iovec wr_iovec1[] = {
     54 	{buf, -1},
     55 };
     56 
     57 static struct iovec wr_iovec2[] = {
     58 	{buf, CHUNK},
     59 };
     60 
     61 static struct iovec wr_iovec3[] = {
     62 	{(char *)-1, CHUNK},
     63 };
     64 
     65 static struct tcase {
     66 	int *fd;
     67 	struct iovec *name;
     68 	int count;
     69 	off_t offset;
     70 	int exp_err;
     71 } tcases[] = {
     72 	{&fd1, wr_iovec1, 1, 0, EINVAL},
     73 	{&fd1, wr_iovec2, -1, 0, EINVAL},
     74 	{&fd1, wr_iovec2, 1, -1, EINVAL},
     75 	{&fd1, wr_iovec3, 1, 0, EFAULT},
     76 	{&fd3, wr_iovec2, 1, 0, EBADF},
     77 	{&fd2, wr_iovec2, 1, 0, EBADF},
     78 	{&fd4[1], wr_iovec2, 1, 0, ESPIPE}
     79 };
     80 
     81 static void verify_pwritev(unsigned int n)
     82 {
     83 	struct tcase *tc = &tcases[n];
     84 
     85 	TEST(pwritev(*tc->fd, tc->name, tc->count, tc->offset));
     86 	if (TEST_RETURN == 0) {
     87 		tst_res(TFAIL, "pwritev() succeeded unexpectedly");
     88 		return;
     89 	}
     90 
     91 	if (TEST_ERRNO == tc->exp_err) {
     92 		tst_res(TPASS | TTERRNO, "pwritev() failed as expected");
     93 		return;
     94 	}
     95 
     96 	tst_res(TFAIL | TTERRNO, "pwritev() failed unexpectedly, expected %s",
     97 		tst_strerrno(tc->exp_err));
     98 }
     99 
    100 static void setup(void)
    101 {
    102 	fd1 = SAFE_OPEN("file", O_RDWR | O_CREAT, 0644);
    103 	SAFE_FTRUNCATE(fd1, getpagesize());
    104 	fd2 = SAFE_OPEN("file", O_RDONLY | O_CREAT, 0644);
    105 	SAFE_PIPE(fd4);
    106 }
    107 
    108 static void cleanup(void)
    109 {
    110 	if (fd1 > 0 && close(fd1))
    111 		tst_res(TWARN | TERRNO, "failed to close file");
    112 
    113 	if (fd2 > 0 && close(fd2))
    114 		tst_res(TWARN | TERRNO, "failed to close file");
    115 
    116 	if (fd4[0] > 0 && close(fd4[0]))
    117 		tst_res(TWARN | TERRNO, "failed to close file");
    118 
    119 	if (fd4[1] > 0 && close(fd4[1]))
    120 		tst_res(TWARN | TERRNO, "failed to close file");
    121 }
    122 
    123 static struct tst_test test = {
    124 	.tid = "pwritev02",
    125 	.tcnt = ARRAY_SIZE(tcases),
    126 	.setup = setup,
    127 	.cleanup = cleanup,
    128 	.test = verify_pwritev,
    129 	.min_kver = "2.6.30",
    130 	.needs_tmpdir = 1,
    131 };
    132