Back to index

glibc  2.9
tst-pselect.c
Go to the documentation of this file.
00001 #include <errno.h>
00002 #include <signal.h>
00003 #include <stdio.h>
00004 #include <unistd.h>
00005 #include <sys/select.h>
00006 #include <sys/wait.h>
00007 
00008 
00009 static volatile int handler_called;
00010 
00011 static void
00012 handler (int sig)
00013 {
00014   handler_called = 1;
00015 }
00016 
00017 
00018 static int
00019 do_test (void)
00020 {
00021   struct sigaction sa;
00022   sa.sa_handler = handler;
00023   sa.sa_flags = 0;
00024   sigemptyset (&sa.sa_mask);
00025 
00026   if (sigaction (SIGUSR1, &sa, NULL) != 0)
00027     {
00028       puts ("sigaction failed");
00029       return 1;
00030     }
00031 
00032   sa.sa_handler = SIG_IGN;
00033   sa.sa_flags = SA_NOCLDWAIT;
00034 
00035   if (sigaction (SIGCHLD, &sa, NULL) != 0)
00036     {
00037       puts ("2nd sigaction failed");
00038       return 1;
00039     }
00040 
00041   if (sigblock (sigmask (SIGUSR1)) != 0)
00042     {
00043       puts ("sigblock failed");
00044       return 1;
00045     }
00046 
00047   int fds[2][2];
00048 
00049   if (pipe (fds[0]) != 0 || pipe (fds[1]) != 0)
00050     {
00051       puts ("pipe failed");
00052       return 1;
00053     }
00054 
00055   fd_set rfds;
00056   FD_ZERO (&rfds);
00057 
00058   sigset_t ss;
00059   sigprocmask (SIG_SETMASK, NULL, &ss);
00060   sigdelset (&ss, SIGUSR1);
00061 
00062   struct timespec to = { .tv_sec = 0, .tv_nsec = 500000000 };
00063 
00064   pid_t parent = getpid ();
00065   pid_t p = fork ();
00066   if (p == 0)
00067     {
00068       close (fds[0][1]);
00069       close (fds[1][0]);
00070 
00071       FD_SET (fds[0][0], &rfds);
00072 
00073       int e;
00074       do
00075        {
00076          if (getppid () != parent)
00077            exit (2);
00078 
00079          errno = 0;
00080          e = pselect (fds[0][0] + 1, &rfds, NULL, NULL, &to, &ss);
00081        }
00082       while (e == 0);
00083 
00084       if (e != -1)
00085        {
00086          puts ("child: pselect did not fail");
00087          return 0;
00088        }
00089       if (errno != EINTR)
00090        {
00091          puts ("child: pselect did not set errno to EINTR");
00092          return 0;
00093        }
00094 
00095       TEMP_FAILURE_RETRY (write (fds[1][1], "foo", 3));
00096 
00097       exit (0);
00098     }
00099 
00100   close (fds[0][0]);
00101   close (fds[1][1]);
00102 
00103   FD_SET (fds[1][0], &rfds);
00104 
00105   kill (p, SIGUSR1);
00106 
00107   int e = pselect (fds[1][0] + 1, &rfds, NULL, NULL, NULL, &ss);
00108   if (e == -1)
00109     {
00110       puts ("parent: pselect failed");
00111       return 1;
00112     }
00113   if (e != 1)
00114     {
00115       puts ("parent: pselect did not report readable fd");
00116       return 1;
00117     }
00118   if (!FD_ISSET (fds[1][0], &rfds))
00119     {
00120       puts ("parent: pselect reports wrong fd");
00121       return 1;
00122     }
00123 
00124   return 0;
00125 }
00126 
00127 #define TEST_FUNCTION do_test ()
00128 #include "../test-skeleton.c"