Fix printing of negative offsets in pread64 and pwrite64 syscalls
* io.c (SYS_FUNC(pread), SYS_FUNC(pwrite)): Print offset using %lld format string. * tests/pread64-pwrite64.c: New file. * tests/pread64-pwrite64.test: New test. * tests/.gitignore: Add pread64-pwrite64. * tests/Makefile.am (check_PROGRAMS): Likewise. (pread64_pwrite64_CPPFLAGS): New variable. (DECODER_TESTS): Add pread64-pwrite64.
This commit is contained in:
parent
69f1bf37fd
commit
9f3a6af09a
4
io.c
4
io.c
@ -169,7 +169,7 @@ SYS_FUNC(pread)
|
||||
else
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
printllval(tcp, "%llu", PREAD_OFFSET_ARG);
|
||||
printllval(tcp, "%lld", PREAD_OFFSET_ARG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -180,7 +180,7 @@ SYS_FUNC(pwrite)
|
||||
tprints(", ");
|
||||
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
||||
tprintf(", %lu, ", tcp->u_arg[2]);
|
||||
printllval(tcp, "%llu", PREAD_OFFSET_ARG);
|
||||
printllval(tcp, "%lld", PREAD_OFFSET_ARG);
|
||||
|
||||
return RVAL_DECODED;
|
||||
}
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -92,6 +92,7 @@ personality
|
||||
pipe
|
||||
poll
|
||||
ppoll
|
||||
pread64-pwrite64
|
||||
preadv
|
||||
preadv-pwritev
|
||||
pselect6
|
||||
|
@ -141,6 +141,7 @@ check_PROGRAMS = \
|
||||
pipe \
|
||||
poll \
|
||||
ppoll \
|
||||
pread64-pwrite64 \
|
||||
preadv \
|
||||
preadv-pwritev \
|
||||
pselect6 \
|
||||
@ -229,6 +230,7 @@ mmap64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
mq_LDADD = -lrt $(LDADD)
|
||||
newfstatat_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
pc_LDADD = $(dl_LIBS) $(LDADD)
|
||||
pread64_pwrite64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
preadv_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
preadv_pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
|
||||
@ -323,6 +325,7 @@ DECODER_TESTS = \
|
||||
pipe.test \
|
||||
poll.test \
|
||||
ppoll.test \
|
||||
pread64-pwrite64.test \
|
||||
preadv.test \
|
||||
preadv-pwritev.test \
|
||||
pselect6.test \
|
||||
|
157
tests/pread64-pwrite64.c
Normal file
157
tests/pread64-pwrite64.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Check decoding of pread64 and pwrite64 syscalls.
|
||||
*
|
||||
* Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
tprintf("%s", "");
|
||||
|
||||
static char tmp[] = "pread64-pwrite64-tmpfile";
|
||||
if (open(tmp, O_CREAT|O_RDONLY|O_TRUNC, 0600) != 0)
|
||||
perror_msg_and_fail("creat: %s", tmp);
|
||||
if (open(tmp, O_WRONLY) != 1)
|
||||
perror_msg_and_fail("open: %s", tmp);
|
||||
|
||||
char *nil = tail_alloc(1);
|
||||
*nil = '\0';
|
||||
|
||||
static const char w_c[] = "0123456789abcde";
|
||||
const unsigned int w_len = LENGTH_OF(w_c);
|
||||
const char *w_d = hexdump_strdup(w_c);
|
||||
const void *w = tail_memdup(w_c, w_len);
|
||||
|
||||
static const char r0_c[] = "01234567";
|
||||
const char *r0_d = hexdump_strdup(r0_c);
|
||||
const unsigned int r0_len = (w_len + 1) / 2;
|
||||
void *r0 = tail_alloc(r0_len);
|
||||
|
||||
static const char r1_c[] = "89abcde";
|
||||
const char *r1_d = hexdump_strdup(r1_c);
|
||||
const unsigned int r1_len = w_len - r0_len;
|
||||
void *r1 = tail_alloc(w_len);
|
||||
|
||||
void *efault = r1 - get_page_size();
|
||||
|
||||
long rc;
|
||||
|
||||
rc = pwrite(1, w, 0, 0);
|
||||
if (rc)
|
||||
perror_msg_and_fail("pwrite64: expected 0, returned %ld", rc);
|
||||
tprintf("pwrite64(1, \"\", 0, 0) = 0\n");
|
||||
|
||||
rc = pwrite(1, w, w_len + 1, 0);
|
||||
if (rc != -1)
|
||||
perror_msg_and_fail("pwrite64: expected -1 EFAULT"
|
||||
", returned %ld", rc);
|
||||
tprintf("pwrite64(1, %p, %u, 0) = -1 EFAULT (%m)\n",
|
||||
w, w_len + 1);
|
||||
|
||||
rc = pwrite(1, nil, 1, -3);
|
||||
if (rc != -1)
|
||||
perror_msg_and_fail("pwrite64: expected -1, returned %ld", rc);
|
||||
tprintf("pwrite64(1, \"\\0\", 1, -3) = -1 EINVAL (%m)\n");
|
||||
|
||||
rc = pwrite(1, w, w_len, 0);
|
||||
if (rc != (int) w_len)
|
||||
perror_msg_and_fail("pwrite64: expected %u, returned %ld",
|
||||
w_len, rc);
|
||||
tprintf("pwrite64(1, \"%s\", %u, 0) = %ld\n"
|
||||
" | 00000 %-49s %-16s |\n",
|
||||
w_c, w_len, rc, w_d, w_c);
|
||||
close(1);
|
||||
|
||||
rc = pread(0, efault, 1, 0);
|
||||
if (rc != -1)
|
||||
perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
|
||||
tprintf("pread64(0, %p, 1, 0) = -1 EFAULT (%m)\n", efault);
|
||||
|
||||
rc = pread(0, efault, 2, -7);
|
||||
if (rc != -1)
|
||||
perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
|
||||
tprintf("pread64(0, %p, 2, -7) = -1 EINVAL (%m)\n", efault);
|
||||
|
||||
rc = pread(0, r0, r0_len, 0);
|
||||
if (rc != (int) r0_len)
|
||||
perror_msg_and_fail("pread64: expected %u, returned %ld",
|
||||
r0_len, rc);
|
||||
tprintf("pread64(0, \"%s\", %u, 0) = %ld\n"
|
||||
" | 00000 %-49s %-16s |\n",
|
||||
r0_c, r0_len, rc, r0_d, r0_c);
|
||||
|
||||
rc = pread(0, r1, w_len, r0_len);
|
||||
if (rc != (int) r1_len)
|
||||
perror_msg_and_fail("pread64: expected %u, returned %ld",
|
||||
r1_len, rc);
|
||||
tprintf("pread64(0, \"%s\", %u, %u) = %ld\n"
|
||||
" | 00000 %-49s %-16s |\n",
|
||||
r1_c, w_len, r0_len, rc, r1_d, r1_c);
|
||||
close(0);
|
||||
|
||||
const off_t offset = 0xdefaceddeadbeefLL;
|
||||
const int rw_len = 8;
|
||||
char *rw_buf = tail_alloc(rw_len);
|
||||
|
||||
if (open("/dev/zero", O_RDONLY))
|
||||
perror_msg_and_fail("open");
|
||||
|
||||
rc = pread(0, rw_buf, rw_len, offset);
|
||||
if (rc != rw_len)
|
||||
perror_msg_and_fail("pread64: expected %d, returned %ld",
|
||||
rw_len, rc);
|
||||
|
||||
tprintf("%s(%d, \"%s\", %d, %lld) = %ld\n"
|
||||
" | 00000 %-49s %-16s |\n",
|
||||
"pread64", 0, "\\0\\0\\0\\0\\0\\0\\0\\0",
|
||||
rw_len, (long long) offset, rc,
|
||||
" 00 00 00 00 00 00 00 00", "........");
|
||||
|
||||
if (open("/dev/null", O_WRONLY) != 1)
|
||||
perror_msg_and_fail("open");
|
||||
|
||||
rc = pwrite(1, rw_buf, rw_len, offset);
|
||||
if (rc != rw_len)
|
||||
perror_msg_and_fail("pwrite64: expected %d, returned %ld",
|
||||
rw_len, rc);
|
||||
|
||||
tprintf("%s(%d, \"%s\", %d, %lld) = %ld\n"
|
||||
" | 00000 %-49s %-16s |\n",
|
||||
"pwrite64", 1, "\\0\\0\\0\\0\\0\\0\\0\\0",
|
||||
rw_len, (long long) offset, rc,
|
||||
" 00 00 00 00 00 00 00 00", "........");
|
||||
|
||||
tprintf("+++ exited with 0 +++\n");
|
||||
return 0;
|
||||
}
|
18
tests/pread64-pwrite64.test
Executable file
18
tests/pread64-pwrite64.test
Executable file
@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check decoding and dumping of pread64 and pwrite64 syscalls.
|
||||
|
||||
. "${srcdir=.}/init.sh"
|
||||
|
||||
# strace -P is implemented using /proc/self/fd
|
||||
[ -d /proc/self/fd/ ] ||
|
||||
framework_skip_ '/proc/self/fd/ is not available'
|
||||
|
||||
tmpfile=pread64-pwrite64-tmpfile
|
||||
> $tmpfile
|
||||
|
||||
run_strace_match_diff \
|
||||
-a22 -eread=0 -ewrite=1 -e trace=pread64,pwrite64 \
|
||||
-P $tmpfile -P /dev/zero -P /dev/null
|
||||
|
||||
rm -f $tmpfile
|
Loading…
x
Reference in New Issue
Block a user