Back to index

glibc  2.9
tst-getpid1.c
Go to the documentation of this file.
00001 #include <sched.h>
00002 #include <signal.h>
00003 #include <string.h>
00004 #include <stdio.h>
00005 #include <unistd.h>
00006 #include <sys/types.h>
00007 #include <sys/wait.h>
00008 #include <stackinfo.h>
00009 
00010 #ifndef TEST_CLONE_FLAGS
00011 #define TEST_CLONE_FLAGS 0
00012 #endif
00013 
00014 static int sig;
00015 
00016 static int
00017 f (void *a)
00018 {
00019   puts ("in f");
00020   union sigval sival;
00021   sival.sival_int = getpid ();
00022   printf ("pid = %d\n", sival.sival_int);
00023   if (sigqueue (getppid (), sig, sival) != 0)
00024     return 1;
00025   return 0;
00026 }
00027 
00028 
00029 static int
00030 do_test (void)
00031 {
00032   int mypid = getpid ();
00033 
00034   sig = SIGRTMIN;
00035   sigset_t ss;
00036   sigemptyset (&ss);
00037   sigaddset (&ss, sig);
00038   if (sigprocmask (SIG_BLOCK, &ss, NULL) != 0)
00039     {
00040       printf ("sigprocmask failed: %m\n");
00041       return 1;
00042     }
00043 
00044 #ifdef __ia64__
00045   extern int __clone2 (int (*__fn) (void *__arg), void *__child_stack_base,
00046                      size_t __child_stack_size, int __flags,
00047                      void *__arg, ...);
00048   char st[256 * 1024] __attribute__ ((aligned));
00049   pid_t p = __clone2 (f, st, sizeof (st), TEST_CLONE_FLAGS, 0);
00050 #else
00051   char st[128 * 1024] __attribute__ ((aligned));
00052 # if _STACK_GROWS_DOWN
00053   pid_t p = clone (f, st + sizeof (st), TEST_CLONE_FLAGS, 0);
00054 # elif _STACK_GROWS_UP
00055   pid_t p = clone (f, st, TEST_CLONE_FLAGS, 0);
00056 # else
00057 #  error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
00058 # endif
00059 #endif
00060   if (p == -1)
00061     {
00062       printf("clone failed: %m\n");
00063       return 1;
00064     }
00065   printf ("new thread: %d\n", (int) p);
00066 
00067   siginfo_t si;
00068   do
00069     if (sigwaitinfo (&ss, &si) < 0)
00070       {
00071        printf("sigwaitinfo failed: %m\n");
00072        kill (p, SIGKILL);
00073        return 1;
00074       }
00075   while  (si.si_signo != sig || si.si_code != SI_QUEUE);
00076 
00077   int e;
00078   if (waitpid (p, &e, __WCLONE) != p)
00079     {
00080       puts ("waitpid failed");
00081       kill (p, SIGKILL);
00082       return 1;
00083     }
00084   if (!WIFEXITED (e))
00085     {
00086       if (WIFSIGNALED (e))
00087        printf ("died from signal %s\n", strsignal (WTERMSIG (e)));
00088       else
00089        puts ("did not terminate correctly");
00090       return 1;
00091     }
00092   if (WEXITSTATUS (e) != 0)
00093     {
00094       printf ("exit code %d\n", WEXITSTATUS (e));
00095       return 1;
00096     }
00097 
00098   if (si.si_int != (int) p)
00099     {
00100       printf ("expected PID %d, got si_int %d\n", (int) p, si.si_int);
00101       kill (p, SIGKILL);
00102       return 1;
00103     }
00104 
00105   if (si.si_pid != p)
00106     {
00107       printf ("expected PID %d, got si_pid %d\n", (int) p, (int) si.si_pid);
00108       kill (p, SIGKILL);
00109       return 1;
00110     }
00111 
00112   if (getpid () != mypid)
00113     {
00114       puts ("my PID changed");
00115       return 1;
00116     }
00117 
00118   return 0;
00119 }
00120 
00121 #define TEST_FUNCTION do_test ()
00122 #include "../test-skeleton.c"