Home | History | Annotate | Download | only in pwrite
      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  * Test Description:
     22  *  Verify that,
     23  *   1) pwrite() fails when attempted to write to an unnamed pipe,
     24  *      returns ESPIPE.
     25  *   2) pwrite() fails if the specified offset position was invalid,
     26  *	returns EINVAL.
     27  *   3) pwrite() fails if fd is not a valid file descriptor,
     28  *	returns EBADF.
     29  *   4) pwrite() fails if fd is not open for writing, return EBADF.
     30  *   5) pwrite() fails when attempted to write with buf outside
     31  *      accessible address space, returns EFAULT.
     32  */
     33 
     34 #define _XOPEN_SOURCE 500
     35 
     36 #include <errno.h>
     37 #include <unistd.h>
     38 #include <string.h>
     39 
     40 #include "tst_test.h"
     41 
     42 #define TEMPFILE "pwrite_file"
     43 #define BS 1024
     44 
     45 static int fd;
     46 static int fd_ro;
     47 static int inv_fd = -1;
     48 static int pipe_fds[2];
     49 static char buf[BS];
     50 
     51 static struct tcase {
     52 	void *buf;
     53 	size_t size;
     54 	int *fd;
     55 	off_t off;
     56 	int exp_errno;
     57 } tcases[] = {
     58 	{buf, sizeof(buf), &pipe_fds[1], 0, ESPIPE},
     59 	{buf, sizeof(buf), &fd, -1, EINVAL},
     60 	{buf, sizeof(buf), &inv_fd, 0, EBADF},
     61 	{buf, sizeof(buf), &fd_ro, 0, EBADF},
     62 	{NULL, sizeof(buf), &fd, 0, EFAULT},
     63 };
     64 
     65 /*
     66  * sighandler - handle SIGXFSZ
     67  *
     68  * This is here to start looking at a failure in test case #2.  This
     69  * test case passes on a machine running RedHat 6.2 but it will fail
     70  * on a machine running RedHat 7.1.
     71  */
     72 static void sighandler(int sig)
     73 {
     74 	int ret;
     75 
     76 	if (sig != SIGXFSZ) {
     77 		ret = write(STDOUT_FILENO, "get wrong signal\n",
     78 		            sizeof("get wrong signal\n"));
     79 	} else {
     80 		ret = write(STDOUT_FILENO, "caught SIGXFSZ\n",
     81 		            sizeof("caught SIGXFSZ\n"));
     82 	}
     83 
     84 	(void)ret;
     85 }
     86 
     87 static void verify_pwrite(unsigned int i)
     88 {
     89 	struct tcase *tc = &tcases[i];
     90 
     91 	TEST(pwrite(*tc->fd, tc->buf, BS, tc->off));
     92 
     93 	if (TST_RET >= 0) {
     94 		tst_res(TFAIL, "call succeeded unexpectedly");
     95 		return;
     96 	}
     97 
     98 	if (TST_ERR != tc->exp_errno) {
     99 		tst_res(TFAIL | TTERRNO,
    100 			"pwrite failed unexpectedly, expected %s",
    101 			tst_strerrno(tc->exp_errno));
    102 	}
    103 
    104 	tst_res(TPASS | TTERRNO, "pwrite failed as expected");
    105 }
    106 
    107 static void setup(void)
    108 {
    109 	SAFE_SIGNAL(SIGXFSZ, sighandler);
    110 
    111 	SAFE_PIPE(pipe_fds);
    112 
    113 	fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
    114 	fd_ro = SAFE_OPEN(TEMPFILE, O_RDONLY | O_CREAT, 0666);
    115 }
    116 
    117 static void cleanup(void)
    118 {
    119 	if (fd > 0)
    120 		SAFE_CLOSE(fd);
    121 
    122 	if (fd_ro > 0)
    123 		SAFE_CLOSE(fd_ro);
    124 
    125 	if (pipe_fds[0] > 0)
    126 		SAFE_CLOSE(pipe_fds[0]);
    127 
    128 	if (pipe_fds[1] > 0)
    129 		SAFE_CLOSE(pipe_fds[1]);
    130 }
    131 
    132 static struct tst_test test = {
    133 	.needs_tmpdir = 1,
    134 	.setup = setup,
    135 	.cleanup = cleanup,
    136 	.test = verify_pwrite,
    137 	.tcnt = ARRAY_SIZE(tcases),
    138 };
    139