Home | History | Annotate | Line # | Download | only in sys
t_write.c revision 1.2.24.1
      1  1.2.24.1  pgoyette /* $NetBSD: t_write.c,v 1.2.24.1 2017/03/20 06:57:59 pgoyette Exp $ */
      2       1.1    jruoho 
      3       1.1    jruoho /*-
      4       1.1    jruoho  * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
      5       1.1    jruoho  * All rights reserved.
      6       1.1    jruoho  *
      7       1.1    jruoho  * Redistribution and use in source and binary forms, with or without
      8       1.1    jruoho  * modification, are permitted provided that the following conditions
      9       1.1    jruoho  * are met:
     10       1.1    jruoho  * 1. Redistributions of source code must retain the above copyright
     11       1.1    jruoho  *    notice, this list of conditions and the following disclaimer.
     12       1.1    jruoho  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1    jruoho  *    notice, this list of conditions and the following disclaimer in the
     14       1.1    jruoho  *    documentation and/or other materials provided with the distribution.
     15       1.1    jruoho  *
     16       1.1    jruoho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17       1.1    jruoho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18       1.1    jruoho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19       1.1    jruoho  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20       1.1    jruoho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21       1.1    jruoho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22       1.1    jruoho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23       1.1    jruoho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24       1.1    jruoho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25       1.1    jruoho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26       1.1    jruoho  * POSSIBILITY OF SUCH DAMAGE.
     27       1.1    jruoho  */
     28       1.1    jruoho 
     29       1.1    jruoho #include <sys/cdefs.h>
     30       1.1    jruoho __COPYRIGHT("@(#) Copyright (c) 2008\
     31       1.1    jruoho  The NetBSD Foundation, inc. All rights reserved.");
     32  1.2.24.1  pgoyette __RCSID("$NetBSD: t_write.c,v 1.2.24.1 2017/03/20 06:57:59 pgoyette Exp $");
     33       1.1    jruoho 
     34       1.1    jruoho #include <sys/uio.h>
     35       1.1    jruoho 
     36       1.1    jruoho #include <atf-c.h>
     37       1.1    jruoho #include <errno.h>
     38       1.2    jruoho #include <fcntl.h>
     39       1.2    jruoho #include <signal.h>
     40  1.2.24.1  pgoyette #include <limits.h>
     41       1.1    jruoho #include <stdio.h>
     42       1.2    jruoho #include <stdint.h>
     43       1.1    jruoho #include <string.h>
     44       1.1    jruoho #include <unistd.h>
     45       1.1    jruoho 
     46       1.2    jruoho static void		 sighandler(int);
     47       1.2    jruoho 
     48       1.2    jruoho static bool		 fail = false;
     49       1.2    jruoho static const char	*path = "write";
     50       1.2    jruoho 
     51       1.2    jruoho static void
     52  1.2.24.1  pgoyette sighandler(int signo __unused)
     53       1.2    jruoho {
     54       1.2    jruoho 	fail = false;
     55       1.2    jruoho }
     56       1.2    jruoho 
     57       1.2    jruoho ATF_TC_WITH_CLEANUP(write_err);
     58       1.2    jruoho ATF_TC_HEAD(write_err, tc)
     59       1.2    jruoho {
     60       1.2    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)");
     61       1.2    jruoho }
     62       1.2    jruoho 
     63       1.2    jruoho ATF_TC_BODY(write_err, tc)
     64       1.2    jruoho {
     65       1.2    jruoho 	char rbuf[3] = { 'a', 'b', 'c' };
     66       1.2    jruoho 	char wbuf[3] = { 'x', 'y', 'z' };
     67       1.2    jruoho 	int fd;
     68       1.2    jruoho 
     69       1.2    jruoho 	errno = 0;
     70       1.2    jruoho 	ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1);
     71       1.2    jruoho 
     72       1.2    jruoho 	fd = open(path, O_RDWR | O_CREAT);
     73       1.2    jruoho 
     74       1.2    jruoho 	if (fd >= 0) {
     75       1.2    jruoho 
     76       1.2    jruoho 		errno = 0;
     77       1.2    jruoho 		ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3);
     78       1.2    jruoho 
     79       1.2    jruoho 		errno = 0;
     80       1.2    jruoho 		ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1);
     81       1.2    jruoho 
     82       1.2    jruoho 		errno = 0;
     83       1.2    jruoho 		ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1);
     84       1.2    jruoho 
     85       1.2    jruoho 		/*
     86       1.2    jruoho 		 * Check that the above bogus write(2)
     87       1.2    jruoho 		 * calls did not corrupt the file.
     88       1.2    jruoho 		 */
     89       1.2    jruoho 		ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0);
     90       1.2    jruoho 		ATF_REQUIRE(read(fd, rbuf, 3) == 3);
     91       1.2    jruoho 		ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0);
     92       1.2    jruoho 
     93       1.2    jruoho 		(void)close(fd);
     94       1.2    jruoho 		(void)unlink(path);
     95       1.2    jruoho 	}
     96       1.2    jruoho }
     97       1.2    jruoho 
     98       1.2    jruoho ATF_TC_CLEANUP(write_err, tc)
     99       1.2    jruoho {
    100       1.2    jruoho 	(void)unlink(path);
    101       1.2    jruoho }
    102       1.2    jruoho 
    103       1.2    jruoho ATF_TC(write_pipe);
    104       1.2    jruoho ATF_TC_HEAD(write_pipe, tc)
    105       1.2    jruoho {
    106       1.2    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)");
    107       1.2    jruoho }
    108       1.2    jruoho 
    109       1.2    jruoho ATF_TC_BODY(write_pipe, tc)
    110       1.2    jruoho {
    111       1.2    jruoho 	int fds[2];
    112       1.2    jruoho 
    113       1.2    jruoho 	ATF_REQUIRE(pipe(fds) == 0);
    114       1.2    jruoho 	ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0);
    115       1.2    jruoho 
    116       1.2    jruoho 	ATF_REQUIRE(write(fds[1], "x", 1) != -1);
    117       1.2    jruoho 	ATF_REQUIRE(close(fds[0]) == 0);
    118       1.2    jruoho 
    119       1.2    jruoho 	errno = 0;
    120       1.2    jruoho 	fail = true;
    121       1.2    jruoho 
    122       1.2    jruoho 	if (write(fds[1], "x", 1) != -1 || errno != EPIPE)
    123       1.2    jruoho 		atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded");
    124       1.2    jruoho 
    125       1.2    jruoho 	ATF_REQUIRE(close(fds[1]) == 0);
    126       1.2    jruoho 
    127       1.2    jruoho 	if (fail != false)
    128       1.2    jruoho 		atf_tc_fail_nonfatal("SIGPIPE was not raised");
    129       1.2    jruoho }
    130       1.2    jruoho 
    131       1.2    jruoho ATF_TC_WITH_CLEANUP(write_pos);
    132       1.2    jruoho ATF_TC_HEAD(write_pos, tc)
    133       1.2    jruoho {
    134       1.2    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks that write(2) "
    135       1.2    jruoho 	    "updates the file position");
    136       1.2    jruoho }
    137       1.2    jruoho 
    138       1.2    jruoho ATF_TC_BODY(write_pos, tc)
    139       1.2    jruoho {
    140       1.2    jruoho 	const size_t n = 123;
    141       1.2    jruoho 	size_t i;
    142       1.2    jruoho 	int fd;
    143       1.2    jruoho 
    144       1.2    jruoho 	fd = open(path, O_RDWR | O_CREAT);
    145       1.2    jruoho 	ATF_REQUIRE(fd >= 0);
    146       1.2    jruoho 
    147       1.2    jruoho 	for (i = 0; i < n; i++) {
    148       1.2    jruoho 		ATF_REQUIRE(write(fd, "x", 1) == 1);
    149       1.2    jruoho 		ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1));
    150       1.2    jruoho 	}
    151       1.2    jruoho 
    152       1.2    jruoho 	ATF_REQUIRE(close(fd) == 0);
    153       1.2    jruoho 	ATF_REQUIRE(unlink(path) == 0);
    154       1.2    jruoho }
    155       1.2    jruoho 
    156       1.2    jruoho ATF_TC_CLEANUP(write_pos, tc)
    157       1.2    jruoho {
    158       1.2    jruoho 	(void)unlink(path);
    159       1.2    jruoho }
    160       1.2    jruoho 
    161       1.2    jruoho ATF_TC_WITH_CLEANUP(write_ret);
    162       1.2    jruoho ATF_TC_HEAD(write_ret, tc)
    163       1.2    jruoho {
    164       1.2    jruoho 	atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)");
    165       1.2    jruoho }
    166       1.2    jruoho 
    167       1.2    jruoho ATF_TC_BODY(write_ret, tc)
    168       1.2    jruoho {
    169       1.2    jruoho 	const size_t n = 99;
    170       1.2    jruoho 	char buf[123];
    171       1.2    jruoho 	size_t i, j;
    172       1.2    jruoho 	int fd;
    173       1.2    jruoho 
    174       1.2    jruoho 	fd = open(path, O_WRONLY | O_CREAT);
    175       1.2    jruoho 	ATF_REQUIRE(fd >= 0);
    176       1.2    jruoho 
    177       1.2    jruoho 	(void)memset(buf, 'x', sizeof(buf));
    178       1.2    jruoho 
    179       1.2    jruoho 	for (i = j = 0; i < n; i++)
    180       1.2    jruoho 		j += write(fd, buf, sizeof(buf));
    181       1.2    jruoho 
    182       1.2    jruoho 	if (j != n * 123)
    183       1.2    jruoho 		atf_tc_fail("inconsistent return values from write(2)");
    184       1.2    jruoho 
    185       1.2    jruoho 	(void)close(fd);
    186       1.2    jruoho 	(void)unlink(path);
    187       1.2    jruoho }
    188       1.2    jruoho 
    189       1.2    jruoho ATF_TC_CLEANUP(write_ret, tc)
    190       1.2    jruoho {
    191       1.2    jruoho 	(void)unlink(path);
    192       1.2    jruoho }
    193       1.2    jruoho 
    194       1.1    jruoho ATF_TC(writev_iovmax);
    195       1.1    jruoho ATF_TC_HEAD(writev_iovmax, tc)
    196       1.1    jruoho {
    197       1.1    jruoho 	atf_tc_set_md_var(tc, "timeout", "10");
    198       1.1    jruoho 	atf_tc_set_md_var(tc, "descr",
    199       1.1    jruoho 	    "Checks that file descriptor is properly FILE_UNUSE()d "
    200       1.1    jruoho 	    "when iovcnt is greater than IOV_MAX");
    201       1.1    jruoho }
    202       1.1    jruoho 
    203       1.1    jruoho ATF_TC_BODY(writev_iovmax, tc)
    204       1.1    jruoho {
    205       1.1    jruoho 	ssize_t retval;
    206       1.1    jruoho 
    207       1.1    jruoho 	(void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n");
    208       1.1    jruoho 
    209       1.1    jruoho 	errno = 0;
    210       1.1    jruoho 	retval = writev(2, NULL, IOV_MAX + 1);
    211       1.1    jruoho 
    212       1.1    jruoho 	ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
    213       1.1    jruoho 	ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno));
    214       1.1    jruoho }
    215       1.1    jruoho 
    216       1.1    jruoho ATF_TP_ADD_TCS(tp)
    217       1.1    jruoho {
    218       1.2    jruoho 
    219       1.2    jruoho 	ATF_TP_ADD_TC(tp, write_err);
    220       1.2    jruoho 	ATF_TP_ADD_TC(tp, write_pipe);
    221       1.2    jruoho 	ATF_TP_ADD_TC(tp, write_pos);
    222       1.2    jruoho 	ATF_TP_ADD_TC(tp, write_ret);
    223       1.1    jruoho 	ATF_TP_ADD_TC(tp, writev_iovmax);
    224       1.1    jruoho 
    225       1.1    jruoho 	return atf_no_error();
    226       1.1    jruoho }
    227