]> granicus.if.org Git - strace/commitdiff
Fix decoding of epoll_ctl operation argument
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 16 May 2016 21:43:35 +0000 (21:43 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 16 May 2016 21:47:09 +0000 (21:47 +0000)
Consistently treat operation argument of epoll_ctl syscall as int
to match the kernel behaviour.

* epoll.c (SYS_FUNC(epoll_ctl)): Assign 2nd argument of syscall
to a variable of type unsigned int and use it in all subsequent
checks and lookups.
* tests/epoll_ctl.c (invoke_syscall): New function.
(main): Use it.

epoll.c
tests/epoll_ctl.c

diff --git a/epoll.c b/epoll.c
index 20d306c4ef4001737687367664547de639384c39..7382e0c0af6bb18e3aeb9db2fd725129f3448912 100644 (file)
--- a/epoll.c
+++ b/epoll.c
@@ -70,12 +70,13 @@ SYS_FUNC(epoll_ctl)
 {
        printfd(tcp, tcp->u_arg[0]);
        tprints(", ");
-       printxval(epollctls, tcp->u_arg[1], "EPOLL_CTL_???");
+       const unsigned int op = tcp->u_arg[1];
+       printxval(epollctls, op, "EPOLL_CTL_???");
        tprints(", ");
        printfd(tcp, tcp->u_arg[2]);
        tprints(", ");
        struct epoll_event ev;
-       if (EPOLL_CTL_DEL == tcp->u_arg[1])
+       if (EPOLL_CTL_DEL == op)
                printaddr(tcp->u_arg[3]);
        else if (!umove_or_printaddr(tcp, tcp->u_arg[3], &ev))
                print_epoll_event(tcp, &ev, sizeof(ev), 0);
index ffabca173fc8b66b3441828eb28e3365872b84b0..231e2710b35dbedd8a5a047cf4980c2fbb45de05 100644 (file)
@@ -8,22 +8,29 @@
 # include <sys/epoll.h>
 # include <unistd.h>
 
+static long
+invoke_syscall(unsigned long epfd, unsigned long op, unsigned long fd, void *ev)
+{
+       op |= (unsigned long) 0xffffffff00000000;
+       return syscall(__NR_epoll_ctl, epfd, op, fd, (unsigned long) ev);
+}
+
 int
 main(void)
 {
        struct epoll_event *const ev = tail_alloc(sizeof(*ev));
        ev->events = EPOLLIN;
 
-       long rc = syscall(__NR_epoll_ctl, -1, EPOLL_CTL_ADD, -2, ev);
+       long rc = invoke_syscall(-1U, EPOLL_CTL_ADD, -2U, ev);
        printf("epoll_ctl(-1, EPOLL_CTL_ADD, -2, {EPOLLIN,"
               " {u32=%u, u64=%" PRIu64 "}}) = %ld %s (%m)\n",
               ev->data.u32, ev->data.u64, rc, errno2name());
 
-       rc = syscall(__NR_epoll_ctl, -3, EPOLL_CTL_DEL, -4, ev);
+       rc = invoke_syscall(-3U, EPOLL_CTL_DEL, -4U, ev);
        printf("epoll_ctl(-3, EPOLL_CTL_DEL, -4, %p) = %ld %s (%m)\n",
               ev, rc, errno2name());
 
-       rc = syscall(__NR_epoll_ctl, -1L, EPOLL_CTL_MOD, -16L, 0);
+       rc = invoke_syscall(-1UL, EPOLL_CTL_MOD, -16UL, 0);
        printf("epoll_ctl(-1, EPOLL_CTL_MOD, -16, NULL) = %ld %s (%m)\n",
               rc, errno2name());