summaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/tst-clone2.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux/tst-clone2.c')
-rw-r--r--sysdeps/unix/sysv/linux/tst-clone2.c111
1 files changed, 40 insertions, 71 deletions
diff --git a/sysdeps/unix/sysv/linux/tst-clone2.c b/sysdeps/unix/sysv/linux/tst-clone2.c
index 68a7e6d6e2..0da9e54ba2 100644
--- a/sysdeps/unix/sysv/linux/tst-clone2.c
+++ b/sysdeps/unix/sysv/linux/tst-clone2.c
@@ -28,8 +28,14 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/syscall.h>
-#include <tls.h> /* for THREAD_* macros. */
+#include <stackinfo.h> /* For _STACK_GROWS_{UP,DOWN}. */
+
+static int do_test (void);
+
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
static int sig;
static int pipefd[2];
@@ -39,39 +45,35 @@ f (void *a)
{
close (pipefd[0]);
- pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
- pid_t tid = THREAD_GETMEM (THREAD_SELF, tid);
+ pid_t ppid = getppid ();
+ pid_t pid = getpid ();
+ pid_t tid = syscall (__NR_gettid);
- while (write (pipefd[1], &pid, sizeof pid) < 0)
- continue;
- while (write (pipefd[1], &tid, sizeof tid) < 0)
- continue;
+ if (write (pipefd[1], &ppid, sizeof ppid) != sizeof (ppid))
+ FAIL_EXIT1 ("write ppid failed\n");
+ if (write (pipefd[1], &pid, sizeof pid) != sizeof (pid))
+ FAIL_EXIT1 ("write pid failed\n");
+ if (write (pipefd[1], &tid, sizeof tid) != sizeof (tid))
+ FAIL_EXIT1 ("write tid failed\n");
return 0;
}
static int
-clone_test (int clone_flags)
+do_test (void)
{
sig = SIGRTMIN;
sigset_t ss;
sigemptyset (&ss);
sigaddset (&ss, sig);
if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0)
- {
- printf ("sigprocmask failed: %m\n");
- return 1;
- }
+ FAIL_EXIT1 ("sigprocmask failed: %m");
if (pipe2 (pipefd, O_CLOEXEC))
- {
- printf ("sigprocmask failed: %m\n");
- return 1;
- }
-
- pid_t ppid = getpid ();
+ FAIL_EXIT1 ("pipe failed: %m");
+ int clone_flags = 0;
#ifdef __ia64__
extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
size_t __child_stack_size, int __flags,
@@ -88,61 +90,47 @@ clone_test (int clone_flags)
#error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
#endif
#endif
+
close (pipefd[1]);
if (p == -1)
+ FAIL_EXIT1("clone failed: %m");
+
+ pid_t ppid, pid, tid;
+ if (read (pipefd[0], &ppid, sizeof pid) != sizeof pid)
{
- printf ("clone failed: %m\n");
- return 1;
+ kill (p, SIGKILL);
+ FAIL_EXIT1 ("read ppid failed: %m");
}
-
- pid_t pid, tid;
if (read (pipefd[0], &pid, sizeof pid) != sizeof pid)
{
- printf ("read pid failed: %m\n");
kill (p, SIGKILL);
- return 1;
+ FAIL_EXIT1 ("read pid failed: %m");
}
if (read (pipefd[0], &tid, sizeof tid) != sizeof tid)
{
- printf ("read pid failed: %m\n");
kill (p, SIGKILL);
- return 1;
+ FAIL_EXIT1 ("read tid failed: %m");
}
close (pipefd[0]);
int ret = 0;
- /* For CLONE_VM glibc clone implementation does not change the pthread
- pid/tid field. */
- if ((clone_flags & CLONE_VM) == CLONE_VM)
- {
- if ((ppid != pid) || (ppid != tid))
- {
- printf ("parent pid (%i) != received pid/tid (%i/%i)\n",
- (int)ppid, (int)pid, (int)tid);
- ret = 1;
- }
- }
- /* For any other flag clone updates the new pthread pid and tid with
- the clone return value. */
- else
- {
- if ((p != pid) || (p != tid))
- {
- printf ("child pid (%i) != received pid/tid (%i/%i)\n",
- (int)p, (int)pid, (int)tid);
- ret = 1;
- }
- }
+ pid_t own_pid = getpid ();
+ pid_t own_tid = syscall (__NR_gettid);
+
+ /* Some sanity checks for clone syscall: returned ppid should be current
+ pid and both returned tid/pid should be different from current one. */
+ if ((ppid != own_pid) || (pid == own_pid) || (tid == own_tid))
+ FAIL_RET ("ppid=%i pid=%i tid=%i | own_pid=%i own_tid=%i",
+ (int)ppid, (int)pid, (int)tid, (int)own_pid, (int)own_tid);
int e;
if (waitpid (p, &e, __WCLONE) != p)
{
- puts ("waitpid failed");
kill (p, SIGKILL);
- return 1;
+ FAIL_EXIT1 ("waitpid failed");
}
if (!WIFEXITED (e))
{
@@ -150,29 +138,10 @@ clone_test (int clone_flags)
printf ("died from signal %s\n", strsignal (WTERMSIG (e)));
else
puts ("did not terminate correctly");
- return 1;
+ exit (EXIT_FAILURE);
}
if (WEXITSTATUS (e) != 0)
- {
- printf ("exit code %d\n", WEXITSTATUS (e));
- return 1;
- }
+ FAIL_EXIT1 ("exit code %d", WEXITSTATUS (e));
return ret;
}
-
-int
-do_test (void)
-{
- /* First, check that the clone implementation, without any flag, updates
- the struct pthread to contain the new PID and TID. */
- int ret = clone_test (0);
- /* Second, check that with CLONE_VM the struct pthread PID and TID fields
- remain unmodified after the clone. Any modifications would cause problem
- for the parent as described in bug 19957. */
- ret += clone_test (CLONE_VM);
- return ret;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"