]> granicus.if.org Git - strace/commitdiff
Implement decoding of CLONE_PIDFD flag of clone syscall
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 20 Jun 2019 09:49:27 +0000 (09:49 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 20 Jun 2019 09:49:27 +0000 (09:49 +0000)
* clone.c (SYS_FUNC(clone)): Print pidfd returned by the kernel
when CLONE_PIDFD flag is set.
* tests/clone-flags.c (main): Check it.

clone.c
tests/clone-flags.c

diff --git a/clone.c b/clone.c
index 66be1645ae83ba2a4b05e0bf7586ddb58e2329ce..e74a53ce71e051e420985b5772b1acb2ec2b6b01 100644 (file)
--- a/clone.c
+++ b/clone.c
@@ -116,13 +116,18 @@ SYS_FUNC(clone)
                 * I'm trying to figure out whether there is a *legitimate*
                 * use of this flag which we should respect.
                 */
-               if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
+               if ((flags & (CLONE_PARENT_SETTID|CLONE_PIDFD|CLONE_CHILD_SETTID
                              |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
                        return RVAL_DECODED;
        } else {
-               if (flags & CLONE_PARENT_SETTID) {
+               if (flags & (CLONE_PARENT_SETTID|CLONE_PIDFD)) {
+                       kernel_ulong_t addr = tcp->u_arg[ARG_PTID];
+
                        tprints(", parent_tid=");
-                       printnum_int(tcp, tcp->u_arg[ARG_PTID], "%u");
+                       if (flags & CLONE_PARENT_SETTID)
+                               printnum_int(tcp, addr, "%u");
+                       else
+                               printnum_fd(tcp, addr);
                }
                if (flags & CLONE_SETTLS) {
                        tprints(", tls=");
index c6fb49be292f3880a7304827beef190cb668dd61..b7475cfdf1c06db60929f4d029bb3b30970ac71a 100644 (file)
@@ -10,6 +10,7 @@
 #include "tests.h"
 
 #include <errno.h>
+#include <limits.h>
 #include <sched.h>
 #include <signal.h>
 #include <stdio.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
+#define XLAT_MACROS_ONLY
+#include "xlat/clone_flags.h"
+#undef XLAT_MACROS_ONLY
+
 static const int child_exit_status = 42;
 static pid_t pid;
 
@@ -124,5 +129,23 @@ main(void)
               SYSCALL_NAME, child_stack_printed, STACK_SIZE_ARG
               "CLONE_PARENT_SETTID|SIGCHLD", *ptid, pid);
 
+       char buf[PATH_MAX];
+       if (readlink("/proc/self/fd/0", buf, sizeof(buf) - 1) > 0) {
+               *ptid = 0;
+               pid = do_clone(child, child_stack, child_stack_size,
+                              CLONE_PIDFD|SIGCHLD, 0, ptid);
+               char *fname = 0;
+               if (asprintf(&fname, "/proc/self/fd/%d", *ptid) < 0)
+                       perror_msg_and_fail("asprintf");
+               int rc = readlink(fname, buf, sizeof(buf) - 1);
+               if ((unsigned int) rc >= sizeof(buf))
+                       perror_msg_and_fail("readlink");
+               buf[rc] = '\0';
+               printf("%s(child_stack=%#lx" STACK_SIZE_FMT ", flags=%s"
+                      ", parent_tid=[%u<%s>]) = %d\n",
+                      SYSCALL_NAME, child_stack_printed, STACK_SIZE_ARG
+                      "CLONE_PIDFD|SIGCHLD", *ptid, buf, pid);
+       }
+
        return 0;
 }