1d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes/* 2d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org> 339bac055674d23770b9a724221b728e443196ea7Elliott Hughes * Copyright (c) 2015-2017 The strace developers. 4d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * All rights reserved. 5d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 6d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * Redistribution and use in source and binary forms, with or without 7d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * modification, are permitted provided that the following conditions 8d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * are met: 9d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 1. Redistributions of source code must retain the above copyright 10d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * notice, this list of conditions and the following disclaimer. 11d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 12d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * notice, this list of conditions and the following disclaimer in the 13d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * documentation and/or other materials provided with the distribution. 14d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 3. The name of the author may not be used to endorse or promote products 15d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * derived from this software without specific prior written permission. 16d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * 17d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes */ 28d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 29d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#include "tests.h" 30d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#include <asm/unistd.h> 31d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 32d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#ifdef __NR_sendfile64 33d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 34d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <assert.h> 35d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <errno.h> 36d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <fcntl.h> 37d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <stdio.h> 38d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <stdint.h> 39dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes# include <stdlib.h> 40d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <unistd.h> 41d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes# include <sys/socket.h> 42d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 43d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughesint 44dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughesmain(void) 45d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes{ 46d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes (void) close(0); 47d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes if (open("/dev/zero", O_RDONLY) != 0) 48d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes perror_msg_and_skip("open: %s", "/dev/zero"); 49d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 50d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes int sv[2]; 51d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv)) 52d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes perror_msg_and_skip("socketpair"); 53d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 54dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const unsigned int page_size = get_page_size(); 55dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes assert(syscall(__NR_sendfile64, 0, 1, NULL, page_size) == -1); 56d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes if (EBADF != errno) 57d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes perror_msg_and_skip("sendfile64"); 58dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendfile64(0, 1, NULL, %u) = -1 EBADF (%m)\n", page_size); 59dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 60dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes unsigned int file_size = 0; 61dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes socklen_t optlen = sizeof(file_size); 62dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &file_size, &optlen)) 63dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes perror_msg_and_fail("getsockopt"); 64dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (file_size < 1024) 65dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes error_msg_and_skip("SO_SNDBUF too small: %u", file_size); 66dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 67dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes file_size /= 4; 68dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (file_size / 16 > page_size) 69dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes file_size = page_size * 16; 70dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const unsigned int blen = file_size / 3; 71dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes const unsigned int alen = file_size - blen; 72dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes 73dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes static const char fname[] = "sendfile64-tmpfile"; 74dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes int reg_in = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600); 75dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (reg_in < 0) 76dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes perror_msg_and_fail("open: %s", fname); 77dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (unlink(fname)) 78dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes perror_msg_and_fail("unlink: %s", fname); 79dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes if (ftruncate(reg_in, file_size)) 80dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes perror_msg_and_fail("ftruncate: %s", fname); 81d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 8239bac055674d23770b9a724221b728e443196ea7Elliott Hughes TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, p_off); 83d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes void *p = p_off + 1; 84d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes *p_off = 0; 85d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 86dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes assert(syscall(__NR_sendfile64, 0, 1, p, page_size) == -1); 87dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendfile64(0, 1, %p, %u) = -1 EFAULT (%m)\n", p, page_size); 88d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 89d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes assert(syscall(__NR_sendfile64, sv[1], reg_in, NULL, alen) 90d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes == (long) alen); 91dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendfile64(%d, %d, NULL, %u) = %u\n", 92dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes sv[1], reg_in, alen, alen); 93d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 94d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes assert(syscall(__NR_sendfile64, sv[1], reg_in, p_off, alen) 95d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes == (long) alen); 96dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendfile64(%d, %d, [0] => [%u], %u) = %u\n", 97dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes sv[1], reg_in, alen, alen, alen); 98d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 99dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes assert(syscall(__NR_sendfile64, sv[1], reg_in, p_off, file_size + 1) 100d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes == (long) blen); 101dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes printf("sendfile64(%d, %d, [%u] => [%u], %u) = %u\n", 102dc75b01004a0588c1eb3bc26d7248a6e473b2cddElliott Hughes sv[1], reg_in, alen, file_size, file_size + 1, blen); 103d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 104d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes *p_off = 0xcafef00dfacefeedULL; 105d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes assert(syscall(__NR_sendfile64, sv[1], reg_in, p_off, 1) == -1); 106d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes printf("sendfile64(%d, %d, [14627392582579060461], 1)" 107d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes " = -1 EINVAL (%m)\n", sv[1], reg_in); 108d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 109d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes *p_off = 0xfacefeed; 110d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes assert(syscall(__NR_sendfile64, sv[1], reg_in, p_off, 1) == 0); 111d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes printf("sendfile64(%d, %d, [4207869677], 1) = 0\n", sv[1], reg_in); 112d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 113d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes puts("+++ exited with 0 +++"); 114d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes return 0; 115d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes} 116d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 117d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#else 118d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 119d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott HughesSKIP_MAIN_UNDEFINED("__NR_sendfile64") 120d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes 121d35df493b4e7684c50d2d2fa032ee3a7ac228009Elliott Hughes#endif 122