(root)/
strace-6.5/
tests-m32/
preadv.c
       1  /*
       2   * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@strace.io>
       3   * Copyright (c) 2016-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  
      11  #ifdef HAVE_PREADV
      12  
      13  # include <fcntl.h>
      14  # include <stdio.h>
      15  # include <sys/uio.h>
      16  # include <unistd.h>
      17  
      18  # define LEN 8
      19  
      20  static void
      21  print_iov(const struct iovec *iov)
      22  {
      23  	unsigned char *buf = iov->iov_base;
      24  
      25  	fputs("{iov_base=\"", stdout);
      26  	for (unsigned int i = 0; i < iov->iov_len; ++i)
      27  		printf("\\%d", (int) buf[i]);
      28  	printf("\", iov_len=%u}", (unsigned) iov->iov_len);
      29  }
      30  
      31  static void
      32  print_iovec(const struct iovec *iov, unsigned int cnt)
      33  {
      34  	putchar('[');
      35  	for (unsigned int i = 0; i < cnt; ++i) {
      36  		if (i)
      37  			fputs(", ", stdout);
      38  		print_iov(&iov[i]);
      39  	}
      40  	putchar(']');
      41  }
      42  
      43  /* for preadv(0, NULL, 1, -2) */
      44  DIAG_PUSH_IGNORE_NONNULL
      45  
      46  int
      47  main(void)
      48  {
      49  	const off_t offset = 0xdefaceddeadbeefLL;
      50  	char *buf = tail_alloc(LEN);
      51  	TAIL_ALLOC_OBJECT_CONST_PTR(struct iovec, iov);
      52  	iov->iov_base = buf;
      53  	iov->iov_len = LEN;
      54  
      55  	(void) close(0);
      56  	if (open("/dev/zero", O_RDONLY))
      57  		perror_msg_and_fail("open");
      58  
      59  	if (preadv(0, iov, 1, offset) != LEN)
      60  		perror_msg_and_fail("preadv");
      61  	printf("preadv(0, ");
      62  	print_iovec(iov, 1);
      63  	printf(", 1, %lld) = %u\n", (long long) offset, LEN);
      64  
      65  	if (preadv(0, iov, 1, -1) != -1)
      66  		perror_msg_and_fail("preadv");
      67  	printf("preadv(0, [{iov_base=%p, iov_len=%zu}], 1, -1) = "
      68  	       "-1 EINVAL (%m)\n", iov->iov_base, iov->iov_len);
      69  
      70  	if (preadv(0, NULL, 1, -2) != -1)
      71  		perror_msg_and_fail("preadv");
      72  	printf("preadv(0, NULL, 1, -2) = -1 EINVAL (%m)\n");
      73  
      74  	if (preadv(0, iov, 0, -3) != -1)
      75  		perror_msg_and_fail("preadv");
      76  	printf("preadv(0, [], 0, -3) = -1 EINVAL (%m)\n");
      77  
      78  	int fd = create_tmpfile(O_RDWR);
      79  
      80  	static const char w[] = "0123456789abcde";
      81  	if (write(fd, w, LENGTH_OF(w)) != LENGTH_OF(w))
      82  		perror_msg_and_fail("write");
      83  
      84  	static const char r0_c[] = "01234567";
      85  	static const char r1_c[] = "89abcde";
      86  
      87  	const unsigned int r_len = (LENGTH_OF(w) + 1) / 2;
      88  	void *r0 = tail_alloc(r_len);
      89  	const struct iovec r0_iov_[] = {
      90  		{
      91  			.iov_base = r0,
      92  			.iov_len = r_len
      93  		}
      94  	};
      95  	const struct iovec *r_iov = tail_memdup(r0_iov_, sizeof(r0_iov_));
      96  
      97  	long rc;
      98  
      99  	rc = preadv(fd, r_iov, ARRAY_SIZE(r0_iov_), 0);
     100  	if (rc != (int) r_len)
     101  		perror_msg_and_fail("preadv: expected %u, returned %ld",
     102  				    r_len, rc);
     103  	printf("preadv(%d, [{iov_base=\"%s\", iov_len=%u}], %u, 0) = %u\n",
     104  	       fd, r0_c, r_len, (unsigned int) ARRAY_SIZE(r0_iov_), r_len);
     105  
     106  	void *r1 = tail_alloc(r_len);
     107  	void *r2 = tail_alloc(LENGTH_OF(w));
     108  	const struct iovec r1_iov_[] = {
     109  		{
     110  			.iov_base = r1,
     111  			.iov_len = r_len
     112  		},
     113  		{
     114  			.iov_base = r2,
     115  			.iov_len = LENGTH_OF(w)
     116  		}
     117  	};
     118  	r_iov = tail_memdup(r1_iov_, sizeof(r1_iov_));
     119  
     120  	rc = preadv(fd, r_iov, ARRAY_SIZE(r1_iov_), r_len);
     121  	if (rc != (int) LENGTH_OF(w) - (int) r_len)
     122  		perror_msg_and_fail("preadv: expected %d, returned %ld",
     123  				    (int) LENGTH_OF(w) - r_len, rc);
     124  	printf("preadv(%d, [{iov_base=\"%s\", iov_len=%u}"
     125  	       ", {iov_base=\"\", iov_len=%u}], %u, %u) = %u\n",
     126  	       fd, r1_c, r_len, LENGTH_OF(w),
     127  	       (unsigned int) ARRAY_SIZE(r1_iov_),
     128  	       r_len, LENGTH_OF(w) - r_len);
     129  
     130  	puts("+++ exited with 0 +++");
     131  	return 0;
     132  }
     133  
     134  DIAG_POP_IGNORE_NONNULL
     135  
     136  #else
     137  
     138  SKIP_MAIN_UNDEFINED("HAVE_PREADV")
     139  
     140  #endif