xref: /illumos-gate/usr/src/test/os-tests/tests/writev.c (revision 1e56f352c1c208679012bca47d552e127f5b1072)
181c3d085SJerry Jelinek /*
281c3d085SJerry Jelinek  * This file and its contents are supplied under the terms of the
381c3d085SJerry Jelinek  * Common Development and Distribution License ("CDDL"), version 1.0.
481c3d085SJerry Jelinek  * You may only use this file in accordance with the terms of version
581c3d085SJerry Jelinek  * 1.0 of the CDDL.
681c3d085SJerry Jelinek  *
781c3d085SJerry Jelinek  * A full copy of the text of the CDDL should have accompanied this
881c3d085SJerry Jelinek  * source.  A copy of the CDDL is also available via the Internet at
981c3d085SJerry Jelinek  * http://www.illumos.org/license/CDDL.
1081c3d085SJerry Jelinek  */
1181c3d085SJerry Jelinek 
1281c3d085SJerry Jelinek /*
1381c3d085SJerry Jelinek  * Copyright 2020 Joyent, Inc.
1481c3d085SJerry Jelinek  */
1581c3d085SJerry Jelinek 
1681c3d085SJerry Jelinek /*
1781c3d085SJerry Jelinek  * Some simple testing of the read/writev() family: specifically we're checking
1881c3d085SJerry Jelinek  * IOV_MAX == 1024, and that a large-file compiled 32-bit binary can correctly
1981c3d085SJerry Jelinek  * access certain offsets.
2081c3d085SJerry Jelinek  */
2181c3d085SJerry Jelinek 
2281c3d085SJerry Jelinek #include <sys/uio.h>
2381c3d085SJerry Jelinek #include <strings.h>
2481c3d085SJerry Jelinek #include <limits.h>
2581c3d085SJerry Jelinek #include <unistd.h>
2681c3d085SJerry Jelinek #include <stdlib.h>
2781c3d085SJerry Jelinek #include <stdio.h>
2881c3d085SJerry Jelinek #include <errno.h>
2981c3d085SJerry Jelinek #include <err.h>
3081c3d085SJerry Jelinek 
3181c3d085SJerry Jelinek #define	ONE_GIG ((off_t)1024 * 1024 * 1024)
3281c3d085SJerry Jelinek 
3381c3d085SJerry Jelinek #define	DATA_LEN (sizeof ("data"))
3481c3d085SJerry Jelinek 
3581c3d085SJerry Jelinek char path[] = "/var/tmp/writev_test.XXXXXX";
3681c3d085SJerry Jelinek 
3781c3d085SJerry Jelinek static void
cleanup(void)3881c3d085SJerry Jelinek cleanup(void)
3981c3d085SJerry Jelinek {
4081c3d085SJerry Jelinek 	(void) unlink(path);
4181c3d085SJerry Jelinek }
4281c3d085SJerry Jelinek 
4381c3d085SJerry Jelinek int
main(int argc,char * argv[])4481c3d085SJerry Jelinek main(int argc, char *argv[])
4581c3d085SJerry Jelinek {
4681c3d085SJerry Jelinek 	char data[(IOV_MAX + 1) * DATA_LEN] = "";
4781c3d085SJerry Jelinek 	struct iovec iov[IOV_MAX + 1];
4881c3d085SJerry Jelinek 
4981c3d085SJerry Jelinek 	if (IOV_MAX != 1024)
5081c3d085SJerry Jelinek 		errx(EXIT_FAILURE, "IOV_MAX != 1024");
5181c3d085SJerry Jelinek 
5281c3d085SJerry Jelinek 	int fd = mkstemp(path);
5381c3d085SJerry Jelinek 
5481c3d085SJerry Jelinek 	if (fd == -1)
5581c3d085SJerry Jelinek 		err(EXIT_FAILURE, "failed to create file");
5681c3d085SJerry Jelinek 
5781c3d085SJerry Jelinek 	(void) atexit(cleanup);
5881c3d085SJerry Jelinek 
5981c3d085SJerry Jelinek 	int ret = ftruncate(fd, ONE_GIG * 8);
6081c3d085SJerry Jelinek 
6181c3d085SJerry Jelinek 	if (ret != 0)
6281c3d085SJerry Jelinek 		err(EXIT_FAILURE, "failed to truncate file");
6381c3d085SJerry Jelinek 
6481c3d085SJerry Jelinek 	for (int i = 0; i < IOV_MAX + 1; i++) {
6581c3d085SJerry Jelinek 		(void) strcpy(data + i * DATA_LEN, "data");
6681c3d085SJerry Jelinek 		iov[i].iov_base = data + i * 5;
6781c3d085SJerry Jelinek 		iov[i].iov_len = DATA_LEN;
6881c3d085SJerry Jelinek 	}
6981c3d085SJerry Jelinek 
7081c3d085SJerry Jelinek 	ssize_t written = writev(fd, iov, IOV_MAX + 1);
7181c3d085SJerry Jelinek 
7281c3d085SJerry Jelinek 	if (written != -1 || errno != EINVAL)
7381c3d085SJerry Jelinek 		errx(EXIT_FAILURE, "writev(IOV_MAX + 1) didn't fail properly");
7481c3d085SJerry Jelinek 
7581c3d085SJerry Jelinek 	written = writev(fd, iov, IOV_MAX);
7681c3d085SJerry Jelinek 
7781c3d085SJerry Jelinek 	if (written == -1)
7881c3d085SJerry Jelinek 		err(EXIT_FAILURE, "writev failed");
7981c3d085SJerry Jelinek 
8081c3d085SJerry Jelinek 	bzero(data, sizeof (data));
8181c3d085SJerry Jelinek 
8281c3d085SJerry Jelinek 	ssize_t read = preadv(fd, iov, IOV_MAX, 0);
8381c3d085SJerry Jelinek 
8481c3d085SJerry Jelinek 	if (read != DATA_LEN * IOV_MAX)
8581c3d085SJerry Jelinek 		err(EXIT_FAILURE, "preadv failed");
8681c3d085SJerry Jelinek 
8781c3d085SJerry Jelinek 	for (int i = 0; i < IOV_MAX; i++) {
8881c3d085SJerry Jelinek 		if (strcmp(data + i * DATA_LEN, "data") != 0)
89*1e56f352SRobert Mustacchi 			errx(EXIT_FAILURE, "bad read at 0x%zx", i * DATA_LEN);
9081c3d085SJerry Jelinek 	}
9181c3d085SJerry Jelinek 
9281c3d085SJerry Jelinek 	/*
9381c3d085SJerry Jelinek 	 * Now test various "interesting" offsets.
9481c3d085SJerry Jelinek 	 */
9581c3d085SJerry Jelinek 
9681c3d085SJerry Jelinek 	for (off_t off = 0; off < ONE_GIG * 8; off += ONE_GIG) {
9781c3d085SJerry Jelinek 		if ((written = pwritev(fd, iov, 1, off)) != DATA_LEN)
98*1e56f352SRobert Mustacchi 			err(EXIT_FAILURE, "pwritev(0x%" PRIx64 ") failed", off);
9981c3d085SJerry Jelinek 	}
10081c3d085SJerry Jelinek 
10181c3d085SJerry Jelinek 	for (off_t off = 0; off < ONE_GIG * 8; off += ONE_GIG) {
10281c3d085SJerry Jelinek 		if ((read = preadv(fd, iov, 1, off)) != DATA_LEN)
103*1e56f352SRobert Mustacchi 			err(EXIT_FAILURE, "preadv(0x%" PRIx64 ") failed", off);
10481c3d085SJerry Jelinek 		if (strcmp(data, "data") != 0)
105*1e56f352SRobert Mustacchi 			errx(EXIT_FAILURE, "bad read at 0x%" PRIx64, off);
10681c3d085SJerry Jelinek 	}
10781c3d085SJerry Jelinek 
10881c3d085SJerry Jelinek 	return (EXIT_SUCCESS);
10981c3d085SJerry Jelinek }
110