(root)/
strace-6.5/
tests-m32/
pread64-pwrite64.c
       1  /*
       2   * Check decoding of pread64 and pwrite64 syscalls.
       3   *
       4   * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2021 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  
      13  #include <fcntl.h>
      14  #include <stdio.h>
      15  #include <stdlib.h>
      16  #include <unistd.h>
      17  
      18  static void
      19  dump_str(const char *str, const unsigned int len)
      20  {
      21  	static const char dots[16] = "................";
      22  
      23  	for (unsigned int i = 0; i < len; i += 16) {
      24  		unsigned int n = len - i > 16 ? 16 : len - i;
      25  		const char *dump = hexdump_memdup(str + i, n);
      26  
      27  		tprintf(" | %05x %-49s  %-16.*s |\n",
      28  			i, dump, n, dots);
      29  
      30  		free((void *) dump);
      31  	}
      32  }
      33  
      34  static void
      35  print_hex(const char *str, const unsigned int len)
      36  {
      37  	const unsigned char *ustr = (const unsigned char *) str;
      38  
      39  	for (unsigned int i = 0; i < len; ++i) {
      40  		unsigned int c = ustr[i];
      41  
      42  		switch (c) {
      43  		case '\t':
      44  			tprintf("\\t"); break;
      45  		case '\n':
      46  			tprintf("\\n"); break;
      47  		case '\v':
      48  			tprintf("\\v"); break;
      49  		case '\f':
      50  			tprintf("\\f"); break;
      51  		case '\r':
      52  			tprintf("\\r"); break;
      53  		default:
      54  			tprintf("\\%o", ustr[i]);
      55  		}
      56  	}
      57  }
      58  
      59  static void
      60  test_dump(const unsigned int len)
      61  {
      62  	static char *buf;
      63  
      64  	if (buf) {
      65  		size_t ps1 = get_page_size() - 1;
      66  		buf = (void *) (((size_t) buf + ps1) & ~ps1) - len;
      67  	} else {
      68  		buf = tail_alloc(len);
      69  	}
      70  
      71  	const off_t offset = 0xdefaceddeadbeefLL + len;
      72  	long rc = pread(0, buf, len, offset);
      73  	if (rc != (int) len)
      74  		perror_msg_and_fail("pread64: expected %d, returned %ld",
      75  				    len, rc);
      76  
      77  	tprintf("%s(%d, \"", "pread64", 0);
      78  	print_hex(buf, len);
      79  	tprintf("\", %d, %lld) = %ld\n", len, (long long) offset, rc);
      80  	dump_str(buf, len);
      81  
      82  	for (unsigned int i = 0; i < len; ++i)
      83  		buf[i] = i;
      84  
      85  	rc = pwrite(1, buf, len, offset);
      86  	if (rc != (int) len)
      87  		perror_msg_and_fail("pwrite64: expected %d, returned %ld",
      88  				    len, rc);
      89  
      90  	tprintf("%s(%d, \"", "pwrite64", 1);
      91  	print_hex(buf, len);
      92  	tprintf("\", %d, %lld) = %ld\n", len, (long long) offset, rc);
      93  	dump_str(buf, len);
      94  
      95  	if (!len)
      96  		buf = 0;
      97  }
      98  
      99  int
     100  main(void)
     101  {
     102  	tprintf("%s", "");
     103  
     104  	skip_if_unavailable("/proc/self/fd/");
     105  
     106  	static const char tmp[] = "pread64-pwrite64-tmpfile";
     107  	if (open(tmp, O_CREAT|O_RDONLY|O_TRUNC, 0600) != 0)
     108  		perror_msg_and_fail("creat: %s", tmp);
     109  	if (open(tmp, O_WRONLY) != 1)
     110  		perror_msg_and_fail("open: %s", tmp);
     111  
     112  	char *nil = tail_alloc(1);
     113  	*nil = '\0';
     114  
     115  	static const char w_c[] = "0123456789abcde";
     116  	const unsigned int w_len = LENGTH_OF(w_c);
     117  	const char *w_d = hexdump_strdup(w_c);
     118  	const void *w = tail_memdup(w_c, w_len);
     119  
     120  	static const char r0_c[] = "01234567";
     121  	const char *r0_d = hexdump_strdup(r0_c);
     122  	const unsigned int r0_len = (w_len + 1) / 2;
     123  	void *r0 = tail_alloc(r0_len);
     124  
     125  	static const char r1_c[] = "89abcde";
     126  	const char *r1_d = hexdump_strdup(r1_c);
     127  	const unsigned int r1_len = w_len - r0_len;
     128  	void *r1 = tail_alloc(w_len);
     129  
     130  	void *efault = r1 - get_page_size();
     131  
     132  	long rc;
     133  
     134  	rc = pwrite(1, w, 0, 0);
     135  	if (rc)
     136  		perror_msg_and_fail("pwrite64: expected 0, returned %ld", rc);
     137  	tprintf("pwrite64(1, \"\", 0, 0) = 0\n");
     138  
     139  	rc = pwrite(1, efault, 1, 0);
     140  	if (rc != -1)
     141  		perror_msg_and_fail("pwrite64: expected -1 EFAULT"
     142  				    ", returned %ld", rc);
     143  	tprintf("pwrite64(1, %p, 1, 0) = -1 EFAULT (%m)\n", efault);
     144  
     145  	rc = pwrite(1, nil, 1, -3);
     146  	if (rc != -1)
     147  		perror_msg_and_fail("pwrite64: expected -1, returned %ld", rc);
     148  	tprintf("pwrite64(1, \"\\0\", 1, -3) = -1 EINVAL (%m)\n");
     149  	dump_str(nil, 1);
     150  
     151  	rc = pwrite(1, w, w_len, 0);
     152  	if (rc != (int) w_len)
     153  		perror_msg_and_fail("pwrite64: expected %u, returned %ld",
     154  				    w_len, rc);
     155  	tprintf("pwrite64(1, \"%s\", %u, 0) = %ld\n"
     156  		" | 00000 %-49s  %-16s |\n",
     157  		w_c, w_len, rc, w_d, w_c);
     158  	close(1);
     159  
     160  	rc = pread(0, r0, 0, 0);
     161  	if (rc)
     162  		perror_msg_and_fail("pread64: expected 0, returned %ld", rc);
     163  	tprintf("pread64(0, \"\", 0, 0) = 0\n");
     164  
     165  	rc = pread(0, efault, 1, 0);
     166  	if (rc != -1)
     167  		perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
     168  	tprintf("pread64(0, %p, 1, 0) = -1 EFAULT (%m)\n", efault);
     169  
     170  	rc = pread(0, efault, 2, -7);
     171  	if (rc != -1)
     172  		perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
     173  	tprintf("pread64(0, %p, 2, -7) = -1 EINVAL (%m)\n", efault);
     174  
     175  	rc = pread(0, r0, r0_len, 0);
     176  	if (rc != (int) r0_len)
     177  		perror_msg_and_fail("pread64: expected %u, returned %ld",
     178  				    r0_len, rc);
     179  	tprintf("pread64(0, \"%s\", %u, 0) = %ld\n"
     180  		" | 00000 %-49s  %-16s |\n",
     181  		r0_c, r0_len, rc, r0_d, r0_c);
     182  
     183  	rc = pread(0, r1, w_len, r0_len);
     184  	if (rc != (int) r1_len)
     185  		perror_msg_and_fail("pread64: expected %u, returned %ld",
     186  				    r1_len, rc);
     187  	tprintf("pread64(0, \"%s\", %u, %u) = %ld\n"
     188  		" | 00000 %-49s  %-16s |\n",
     189  		r1_c, w_len, r0_len, rc, r1_d, r1_c);
     190  	close(0);
     191  
     192  	if (open("/dev/zero", O_RDONLY))
     193  		perror_msg_and_fail("open");
     194  
     195  	if (open("/dev/null", O_WRONLY) != 1)
     196  		perror_msg_and_fail("open");
     197  
     198  	for (unsigned int i = 0; i <= 32; ++i)
     199  		test_dump(i);
     200  
     201  	tprintf("+++ exited with 0 +++\n");
     202  	return 0;
     203  }