Back to index

glibc  2.9
Defines | Functions | Variables
tst-cancel4.c File Reference
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/msg.h>
#include <sys/poll.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <sys/wait.h>
#include "pthreadP.h"
#include "../test-skeleton.c"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define IPC_ADDVAL   0
#define WRITE_BUFFER_SIZE   4096
#define WEXITED   0
#define ADD_TEST(name, nbar, early)   { #name, tf_##name, nbar, early }
#define ntest_tf   (sizeof (tests) / sizeof (tests[0]))
#define TIMEOUT   60
#define TEST_FUNCTION   do_test ()

Functions

static void cl (void *arg)
static void * tf_read (void *arg)
static void * tf_readv (void *arg)
static void * tf_write (void *arg)
static void * tf_writev (void *arg)
static void * tf_sleep (void *arg)
static void * tf_usleep (void *arg)
static void * tf_nanosleep (void *arg)
static void * tf_select (void *arg)
static void * tf_pselect (void *arg)
static void * tf_poll (void *arg)
static void * tf_ppoll (void *arg)
static void * tf_wait (void *arg)
static void * tf_waitpid (void *arg)
static void * tf_waitid (void *arg)
static void * tf_sigpause (void *arg)
static void * tf_sigsuspend (void *arg)
static void * tf_sigwait (void *arg)
static void * tf_sigwaitinfo (void *arg)
static void * tf_sigtimedwait (void *arg)
static void * tf_pause (void *arg)
static void * tf_accept (void *arg)
static void * tf_send (void *arg)
static void * tf_recv (void *arg)
static void * tf_recvfrom (void *arg)
static void * tf_recvmsg (void *arg)
static void * tf_open (void *arg)
static void * tf_close (void *arg)
static void * tf_pread (void *arg)
static void * tf_pwrite (void *arg)
static void * tf_fsync (void *arg)
static void * tf_fdatasync (void *arg)
static void * tf_msync (void *arg)
static void * tf_sendto (void *arg)
static void * tf_sendmsg (void *arg)
static void * tf_creat (void *arg)
static void * tf_connect (void *arg)
static void * tf_tcdrain (void *arg)
static void * tf_msgrcv (void *arg)
static void * tf_msgsnd (void *arg)
static int do_test (void)

Variables

static int fds [2]
static int tempfd = -1
static int tempfd2 = -1
static char * tempfname
static int tempmsg = -1
static pthread_barrier_t b2
static int cl_called
struct {
const char * name
void *(* tf )(void *)
int nb
int only_early
tests []

Define Documentation

#define ADD_TEST (   name,
  nbar,
  early 
)    { #name, tf_##name, nbar, early }
#define IPC_ADDVAL   0

Definition at line 84 of file tst-cancel4.c.

#define ntest_tf   (sizeof (tests) / sizeof (tests[0]))

Definition at line 2132 of file tst-cancel4.c.

#define TEST_FUNCTION   do_test ()

Definition at line 2371 of file tst-cancel4.c.

#define TIMEOUT   60

Definition at line 2370 of file tst-cancel4.c.

#define WEXITED   0
#define WRITE_BUFFER_SIZE   4096

Definition at line 87 of file tst-cancel4.c.


Function Documentation

static void cl ( void *  arg) [static]

Definition at line 93 of file tst-cancel4.c.

{
  ++cl_called;
}

Here is the caller graph for this function:

static int do_test ( void  ) [static]

Definition at line 2136 of file tst-cancel4.c.

{
  int val;
  socklen_t len;

  if (socketpair (AF_UNIX, SOCK_STREAM, PF_UNIX, fds) != 0)
    {
      perror ("socketpair");
      exit (1);
    }

  val = 1;
  len = sizeof(val);
  setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
  if (getsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, &len) < 0)
    {
      perror ("getsockopt");
      exit (1);
    }
  if (val >= WRITE_BUFFER_SIZE)
    {
      puts ("minimum write buffer size too large");
      exit (1);
    }
  setsockopt (fds[1], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));

  int result = 0;
  size_t cnt;
  for (cnt = 0; cnt < ntest_tf; ++cnt)
    {
      if (tests[cnt].only_early)
       continue;

      if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
       {
         puts ("b2 init failed");
         exit (1);
       }

      /* Reset the counter for the cleanup handler.  */
      cl_called = 0;

      pthread_t th;
      if (pthread_create (&th, NULL, tests[cnt].tf, NULL) != 0)
       {
         printf ("create for '%s' test failed\n", tests[cnt].name);
         result = 1;
         continue;
       }

      int r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         result = 1;
         continue;
       }

      struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      while (nanosleep (&ts, &ts) != 0)
       continue;

      if (pthread_cancel (th) != 0)
       {
         printf ("cancel for '%s' failed\n", tests[cnt].name);
         result = 1;
         continue;
       }

      void *status;
      if (pthread_join (th, &status) != 0)
       {
         printf ("join for '%s' failed\n", tests[cnt].name);
         result = 1;
         continue;
       }
      if (status != PTHREAD_CANCELED)
       {
         printf ("thread for '%s' not canceled\n", tests[cnt].name);
         result = 1;
         continue;
       }

      if (pthread_barrier_destroy (&b2) != 0)
       {
         puts ("barrier_destroy failed");
         result = 1;
         continue;
       }

      if (cl_called == 0)
       {
         printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
         result = 1;
         continue;
       }
      if (cl_called > 1)
       {
         printf ("cleanup handler called more than once for '%s'\n",
                tests[cnt].name);
         result = 1;
         continue;
       }

      printf ("in-time cancel test of '%s' successful\n", tests[cnt].name);

      if (tempfd != -1)
       {
         close (tempfd);
         tempfd = -1;
       }
      if (tempfd2 != -1)
       {
         close (tempfd2);
         tempfd2 = -1;
       }
      if (tempfname != NULL)
       {
         unlink (tempfname);
         free (tempfname);
         tempfname = NULL;
       }
      if (tempmsg != -1)
       {
         msgctl (tempmsg, IPC_RMID, NULL);
         tempmsg = -1;
       }
    }

  for (cnt = 0; cnt < ntest_tf; ++cnt)
    {
      if (pthread_barrier_init (&b2, NULL, tests[cnt].nb) != 0)
       {
         puts ("b2 init failed");
         exit (1);
       }

      /* Reset the counter for the cleanup handler.  */
      cl_called = 0;

      pthread_t th;
      if (pthread_create (&th, NULL, tests[cnt].tf, (void *) 1l) != 0)
       {
         printf ("create for '%s' test failed\n", tests[cnt].name);
         result = 1;
         continue;
       }

      int r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         result = 1;
         continue;
       }

      if (pthread_cancel (th) != 0)
       {
         printf ("cancel for '%s' failed\n", tests[cnt].name);
         result = 1;
         continue;
       }

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         result = 1;
         continue;
       }

      void *status;
      if (pthread_join (th, &status) != 0)
       {
         printf ("join for '%s' failed\n", tests[cnt].name);
         result = 1;
         continue;
       }
      if (status != PTHREAD_CANCELED)
       {
         printf ("thread for '%s' not canceled\n", tests[cnt].name);
         result = 1;
         continue;
       }

      if (pthread_barrier_destroy (&b2) != 0)
       {
         puts ("barrier_destroy failed");
         result = 1;
         continue;
       }

      if (cl_called == 0)
       {
         printf ("cleanup handler not called for '%s'\n", tests[cnt].name);
         result = 1;
         continue;
       }
      if (cl_called > 1)
       {
         printf ("cleanup handler called more than once for '%s'\n",
                tests[cnt].name);
         result = 1;
         continue;
       }

      printf ("early cancel test of '%s' successful\n", tests[cnt].name);

      if (tempfd != -1)
       {
         close (tempfd);
         tempfd = -1;
       }
      if (tempfd2 != -1)
       {
         close (tempfd2);
         tempfd2 = -1;
       }
      if (tempfname != NULL)
       {
         unlink (tempfname);
         free (tempfname);
         tempfname = NULL;
       }
      if (tempmsg != -1)
       {
         msgctl (tempmsg, IPC_RMID, NULL);
         tempmsg = -1;
       }
    }

  return result;
}

Here is the call graph for this function:

static void* tf_accept ( void *  arg) [static]

Definition at line 977 of file tst-cancel4.c.

{
  struct sockaddr_un sun;
  /* To test a non-blocking accept call we make the call file by using
     a datagrame socket.  */
  int pf = arg == NULL ? SOCK_STREAM : SOCK_DGRAM;

  tempfd = socket (AF_UNIX, pf, 0);
  if (tempfd == -1)
    {
      printf ("%s: socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-1-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);

  unlink (sun.sun_path);

  listen (tempfd, 5);

  socklen_t len = sizeof (sun);

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  accept (tempfd, (struct sockaddr *) &sun, &len);

  pthread_cleanup_pop (0);

  printf ("%s: accept returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_close ( void *  arg) [static]

Definition at line 1404 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which close()
    // blocks we can enable this test to run in both rounds.
    abort ();

  char fname[] = "/tmp/tst-cancel-fd-XXXXXX";
  tempfd = mkstemp (fname);
  if (tempfd == -1)
    {
      printf ("%s: mkstemp failed\n", __FUNCTION__);
      exit (1);
    }
  unlink (fname);

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  close (tempfd);

  pthread_cleanup_pop (0);

  printf ("%s: close returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_connect ( void *  arg) [static]

Definition at line 1858 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which connect()
    // blocks we can enable this test to run in both rounds.
    abort ();

  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);
  tempfname = strdup (sun.sun_path);

  listen (tempfd, 5);

  tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun));

  pthread_cleanup_pop (0);

  printf ("%s: connect returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_creat ( void *  arg) [static]

Definition at line 1824 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which sendmsg()
    // blocks we can enable this test to run in both rounds.
    abort ();

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  creat ("tmp/tst-cancel-4-should-not-exist", 0666);

  pthread_cleanup_pop (0);

  printf ("%s: creat returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_fdatasync ( void *  arg) [static]

Definition at line 1574 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which fdatasync()
    // blocks we can enable this test to run in both rounds.
    abort ();

  tempfd = open ("Makefile", O_RDONLY);
  if (tempfd == -1)
    {
      printf ("%s: cannot open Makefile\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  fdatasync (tempfd);

  pthread_cleanup_pop (0);

  printf ("%s: fdatasync returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_fsync ( void *  arg) [static]

Definition at line 1533 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which fsync()
    // blocks we can enable this test to run in both rounds.
    abort ();

  tempfd = open ("Makefile", O_RDONLY);
  if (tempfd == -1)
    {
      printf ("%s: cannot open Makefile\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  fsync (tempfd);

  pthread_cleanup_pop (0);

  printf ("%s: fsync returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_msgrcv ( void *  arg) [static]

Definition at line 1974 of file tst-cancel4.c.

{
  tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
  if (tempmsg == -1)
    {
      printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  ssize_t s;

  pthread_cleanup_push (cl, NULL);

  struct
  {
    long int type;
    char mem[10];
  } m;
  int randnr;
  /* We need a positive random number.  */
  do
    randnr = random () % 64000;
  while (randnr <= 0);
  do
    {
      errno = 0;
      s = msgrcv (tempmsg, (struct msgbuf *) &m, 10, randnr, 0);
    }
  while (errno == EIDRM || errno == EINTR);

  pthread_cleanup_pop (0);

  printf ("%s: msgrcv returned %zd with errno = %m\n", __FUNCTION__, s);

  msgctl (tempmsg, IPC_RMID, NULL);

  exit (1);
}

Here is the call graph for this function:

static void* tf_msgsnd ( void *  arg) [static]

Definition at line 2032 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which msgsnd()
    // blocks we can enable this test to run in both rounds.
    abort ();

  tempmsg = msgget (IPC_PRIVATE, 0666 | IPC_CREAT);
  if (tempmsg == -1)
    {
      printf ("%s: msgget failed: %s\n", __FUNCTION__, strerror (errno));
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  struct
  {
    long int type;
    char mem[1];
  } m;
  /* We need a positive random number.  */
  do
    m.type = random () % 64000;
  while (m.type <= 0);
  msgsnd (tempmsg, (struct msgbuf *) &m, sizeof (m.mem), 0);

  pthread_cleanup_pop (0);

  printf ("%s: msgsnd returned\n", __FUNCTION__);

  msgctl (tempmsg, IPC_RMID, NULL);

  exit (1);
}

Here is the call graph for this function:

static void* tf_msync ( void *  arg) [static]

Definition at line 1615 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which msync()
    // blocks we can enable this test to run in both rounds.
    abort ();

  tempfd = open ("Makefile", O_RDONLY);
  if (tempfd == -1)
    {
      printf ("%s: cannot open Makefile\n", __FUNCTION__);
      exit (1);
    }
  void *p = mmap (NULL, 10, PROT_READ, MAP_SHARED, tempfd, 0);
  if (p == MAP_FAILED)
    {
      printf ("%s: mmap failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  msync (p, 10, 0);

  pthread_cleanup_pop (0);

  printf ("%s: msync returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_nanosleep ( void *  arg) [static]

Definition at line 349 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  struct timespec ts = { .tv_sec = arg == NULL ? 10000000 : 0, .tv_nsec = 0 };
  TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));

  pthread_cleanup_pop (0);

  printf ("%s: nanosleep returns\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_open ( void *  arg) [static]

Definition at line 1370 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which open()
    // blocks we can enable this test to run in both rounds.
    abort ();

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  open ("Makefile", O_RDONLY);

  pthread_cleanup_pop (0);

  printf ("%s: open returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_pause ( void *  arg) [static]

Definition at line 945 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  pause ();

  pthread_cleanup_pop (0);

  printf ("%s: pause returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_poll ( void *  arg) [static]

Definition at line 480 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };

  int s;
  pthread_cleanup_push (cl, NULL);

  s = poll (rfs, 1, -1);

  pthread_cleanup_pop (0);

  printf ("%s: poll returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_ppoll ( void *  arg) [static]

Definition at line 527 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  struct pollfd rfs[1] = { [0] = { .fd = fd, .events = POLLIN } };

  int s;
  pthread_cleanup_push (cl, NULL);

  s = ppoll (rfs, 1, NULL, NULL);

  pthread_cleanup_pop (0);

  printf ("%s: ppoll returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_pread ( void *  arg) [static]

Definition at line 1447 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which pread()
    // blocks we can enable this test to run in both rounds.
    abort ();

  tempfd = open ("Makefile", O_RDONLY);
  if (tempfd == -1)
    {
      printf ("%s: cannot open Makefile\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  char mem[10];
  pread (tempfd, mem, sizeof (mem), 0);

  pthread_cleanup_pop (0);

  printf ("%s: pread returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_pselect ( void *  arg) [static]

Definition at line 431 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  fd_set rfs;
  FD_ZERO (&rfs);
  FD_SET (fd, &rfs);

  int s;
  pthread_cleanup_push (cl, NULL);

  s = pselect (fd + 1, &rfs, NULL, NULL, NULL, NULL);

  pthread_cleanup_pop (0);

  printf ("%s: pselect returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_pwrite ( void *  arg) [static]

Definition at line 1489 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which pwrite()
    // blocks we can enable this test to run in both rounds.
    abort ();

  char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
  tempfd = mkstemp (fname);
  if (tempfd == -1)
    {
      printf ("%s: mkstemp failed\n", __FUNCTION__);
      exit (1);
    }
  unlink (fname);

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  char mem[10];
  pwrite (tempfd, mem, sizeof (mem), 0);

  pthread_cleanup_pop (0);

  printf ("%s: pwrite returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_read ( void *  arg) [static]

Definition at line 101 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  ssize_t s;
  pthread_cleanup_push (cl, NULL);

  char buf[100];
  s = read (fd, buf, sizeof (buf));

  pthread_cleanup_pop (0);

  printf ("%s: read returns with %zd\n", __FUNCTION__, s);

  exit (1);
}

Here is the call graph for this function:

static void* tf_readv ( void *  arg) [static]

Definition at line 146 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  ssize_t s;
  pthread_cleanup_push (cl, NULL);

  char buf[100];
  struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
  s = readv (fd, iov, 1);

  pthread_cleanup_pop (0);

  printf ("%s: readv returns with %zd\n", __FUNCTION__, s);

  exit (1);
}

Here is the call graph for this function:

static void* tf_recv ( void *  arg) [static]

Definition at line 1130 of file tst-cancel4.c.

{
  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-3-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);

  listen (tempfd, 5);

  tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
    {
      printf ("%s: connect failed\n", __FUNCTION__);
      exit(1);
    }

  unlink (sun.sun_path);

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  char mem[70];

  recv (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0);

  pthread_cleanup_pop (0);

  printf ("%s: recv returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_recvfrom ( void *  arg) [static]

Definition at line 1211 of file tst-cancel4.c.

{
  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-4-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);

  tempfname = strdup (sun.sun_path);

  tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  char mem[70];
  socklen_t len = sizeof (sun);

  recvfrom (tempfd2, mem, arg == NULL ? sizeof (mem) : 0, 0,
           (struct sockaddr *) &sun, &len);

  pthread_cleanup_pop (0);

  printf ("%s: recvfrom returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_recvmsg ( void *  arg) [static]

Definition at line 1286 of file tst-cancel4.c.

{
  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-5-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);

  tempfname = strdup (sun.sun_path);

  tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  char mem[70];
  struct iovec iov[1];
  iov[0].iov_base = mem;
  iov[0].iov_len = arg == NULL ? sizeof (mem) : 0;

  struct msghdr m;
  m.msg_name = &sun;
  m.msg_namelen = sizeof (sun);
  m.msg_iov = iov;
  m.msg_iovlen = 1;
  m.msg_control = NULL;
  m.msg_controllen = 0;

  recvmsg (tempfd2, &m, 0);

  pthread_cleanup_pop (0);

  printf ("%s: recvmsg returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_select ( void *  arg) [static]

Definition at line 382 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[0];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  fd_set rfs;
  FD_ZERO (&rfs);
  FD_SET (fd, &rfs);

  int s;
  pthread_cleanup_push (cl, NULL);

  s = select (fd + 1, &rfs, NULL, NULL, NULL);

  pthread_cleanup_pop (0);

  printf ("%s: select returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_send ( void *  arg) [static]

Definition at line 1048 of file tst-cancel4.c.

{
  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-2-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);

  listen (tempfd, 5);

  tempfd2 = socket (AF_UNIX, SOCK_STREAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  if (connect (tempfd2, (struct sockaddr *) &sun, sizeof (sun)) != 0)
    {
      printf ("%s: connect failed\n", __FUNCTION__);
      exit(1);
    }

  unlink (sun.sun_path);

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  /* Very large block, so that the send call blocks.  */
  char mem[700000];

  send (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0);

  pthread_cleanup_pop (0);

  printf ("%s: send returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sendmsg ( void *  arg) [static]

Definition at line 1738 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which sendmsg()
    // blocks we can enable this test to run in both rounds.
    abort ();

  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);
  tempfname = strdup (sun.sun_path);

  tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  char mem[1];
  struct iovec iov[1];
  iov[0].iov_base = mem;
  iov[0].iov_len = 1;

  struct msghdr m;
  m.msg_name = &sun;
  m.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
                 + strlen (sun.sun_path) + 1);
  m.msg_iov = iov;
  m.msg_iovlen = 1;
  m.msg_control = NULL;
  m.msg_controllen = 0;

  sendmsg (tempfd2, &m, 0);

  pthread_cleanup_pop (0);

  printf ("%s: sendmsg returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sendto ( void *  arg) [static]

Definition at line 1662 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which sendto()
    // blocks we can enable this test to run in both rounds.
    abort ();

  struct sockaddr_un sun;

  tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd == -1)
    {
      printf ("%s: first socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int tries = 0;
  do
    {
      if (++tries > 10)
       {
         printf ("%s: too many unsuccessful bind calls\n", __FUNCTION__);
       }

      strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-6-XXXXXX");
      if (mktemp (sun.sun_path) == NULL)
       {
         printf ("%s: cannot generate temp file name\n", __FUNCTION__);
         exit (1);
       }

      sun.sun_family = AF_UNIX;
    }
  while (bind (tempfd, (struct sockaddr *) &sun,
              offsetof (struct sockaddr_un, sun_path)
              + strlen (sun.sun_path) + 1) != 0);
  tempfname = strdup (sun.sun_path);

  tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
  if (tempfd2 == -1)
    {
      printf ("%s: second socket call failed\n", __FUNCTION__);
      exit (1);
    }

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  pthread_cleanup_push (cl, NULL);

  char mem[1];

  sendto (tempfd2, mem, arg == NULL ? sizeof (mem) : 1, 0,
         (struct sockaddr *) &sun,
         offsetof (struct sockaddr_un, sun_path) + strlen (sun.sun_path) + 1);

  pthread_cleanup_pop (0);

  printf ("%s: sendto returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sigpause ( void *  arg) [static]

Definition at line 741 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  /* Just for fun block the cancellation signal.  We need to use
     __xpg_sigpause since otherwise we will get the BSD version.  */
  __xpg_sigpause (SIGCANCEL);

  pthread_cleanup_pop (0);

  printf ("%s: sigpause returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sigsuspend ( void *  arg) [static]

Definition at line 775 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  /* Just for fun block all signals.  */
  sigset_t mask;
  sigfillset (&mask);
  sigsuspend (&mask);

  pthread_cleanup_pop (0);

  printf ("%s: sigsuspend returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sigtimedwait ( void *  arg) [static]

Definition at line 899 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  /* Block SIGUSR1.  */
  sigset_t mask;
  sigemptyset (&mask);
  sigaddset (&mask, SIGUSR1);
  if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
    {
      printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
      exit (1);
    }

  /* Wait for SIGUSR1.  */
  siginfo_t info;
  struct timespec ts = { .tv_sec = 60, .tv_nsec = 0 };
  pthread_cleanup_push (cl, NULL);

  sigtimedwait (&mask, &info, &ts);

  pthread_cleanup_pop (0);

  printf ("%s: sigtimedwait returned with signal %d\n", __FUNCTION__,
         info.si_signo);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sigwait ( void *  arg) [static]

Definition at line 810 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  /* Block SIGUSR1.  */
  sigset_t mask;
  sigemptyset (&mask);
  sigaddset (&mask, SIGUSR1);
  if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
    {
      printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
      exit (1);
    }

  int sig;
  pthread_cleanup_push (cl, NULL);

  /* Wait for SIGUSR1.  */
  sigwait (&mask, &sig);

  pthread_cleanup_pop (0);

  printf ("%s: sigwait returned with signal %d\n", __FUNCTION__, sig);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sigwaitinfo ( void *  arg) [static]

Definition at line 854 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  /* Block SIGUSR1.  */
  sigset_t mask;
  sigemptyset (&mask);
  sigaddset (&mask, SIGUSR1);
  if (pthread_sigmask (SIG_BLOCK, &mask, NULL) != 0)
    {
      printf ("%s: pthread_sigmask failed\n", __FUNCTION__);
      exit (1);
    }

  siginfo_t info;
  pthread_cleanup_push (cl, NULL);

  /* Wait for SIGUSR1.  */
  sigwaitinfo (&mask, &info);

  pthread_cleanup_pop (0);

  printf ("%s: sigwaitinfo returned with signal %d\n", __FUNCTION__,
         info.si_signo);

  exit (1);
}

Here is the call graph for this function:

static void* tf_sleep ( void *  arg) [static]

Definition at line 285 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  sleep (arg == NULL ? 1000000 : 0);

  pthread_cleanup_pop (0);

  printf ("%s: sleep returns\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_tcdrain ( void *  arg) [static]

Definition at line 1935 of file tst-cancel4.c.

{
  if (arg == NULL)
    // XXX If somebody can provide a portable test case in which tcdrain()
    // blocks we can enable this test to run in both rounds.
    abort ();

  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  /* Regardless of stderr being a terminal, the tcdrain call should be
     canceled.  */
  tcdrain (STDERR_FILENO);

  pthread_cleanup_pop (0);

  printf ("%s: tcdrain returned\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_usleep ( void *  arg) [static]

Definition at line 317 of file tst-cancel4.c.

{
  int r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  if (arg != NULL)
    {
      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: 2nd barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  pthread_cleanup_push (cl, NULL);

  usleep (arg == NULL ? (useconds_t) ULONG_MAX : 0);

  pthread_cleanup_pop (0);

  printf ("%s: usleep returns\n", __FUNCTION__);

  exit (1);
}

Here is the call graph for this function:

static void* tf_wait ( void *  arg) [static]

Definition at line 574 of file tst-cancel4.c.

{
  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      exit (1);
    }

  if (pid == 0)
    {
      /* Make the program disappear after a while.  */
      if (arg == NULL)
       sleep (10);
      exit (0);
    }

  int r;
  if (arg != NULL)
    {
      struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      while (nanosleep (&ts, &ts) != 0)
       continue;

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  int s;
  pthread_cleanup_push (cl, NULL);

  s = wait (NULL);

  pthread_cleanup_pop (0);

  printf ("%s: wait returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_waitid ( void *  arg) [static]

Definition at line 683 of file tst-cancel4.c.

{
  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      exit (1);
    }

  if (pid == 0)
    {
      /* Make the program disappear after a while.  */
      if (arg == NULL)
       sleep (10);
      exit (0);
    }

  int r;
  if (arg != NULL)
    {
      struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      while (nanosleep (&ts, &ts) != 0)
       continue;

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  int s;
  pthread_cleanup_push (cl, NULL);

#ifndef WEXITED
# define WEXITED 0
#endif
  siginfo_t si;
  s = waitid (P_PID, pid, &si, WEXITED);

  pthread_cleanup_pop (0);

  printf ("%s: waitid returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_waitpid ( void *  arg) [static]

Definition at line 628 of file tst-cancel4.c.

{

  pid_t pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      exit (1);
    }

  if (pid == 0)
    {
      /* Make the program disappear after a while.  */
      if (arg == NULL)
       sleep (10);
      exit (0);
    }

  int r;
  if (arg != NULL)
    {
      struct timespec  ts = { .tv_sec = 0, .tv_nsec = 100000000 };
      while (nanosleep (&ts, &ts) != 0)
       continue;

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  int s;
 pthread_cleanup_push (cl, NULL);

  s = waitpid (-1, NULL, 0);

  pthread_cleanup_pop (0);

  printf ("%s: waitpid returns with %d (%s)\n", __FUNCTION__, s,
         strerror (errno));

  exit (1);
}

Here is the call graph for this function:

static void* tf_write ( void *  arg) [static]

Definition at line 192 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[1];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  ssize_t s;
  pthread_cleanup_push (cl, NULL);

  char buf[WRITE_BUFFER_SIZE];
  memset (buf, '\0', sizeof (buf));
  s = write (fd, buf, sizeof (buf));

  pthread_cleanup_pop (0);

  printf ("%s: write returns with %zd\n", __FUNCTION__, s);

  exit (1);
}

Here is the call graph for this function:

static void* tf_writev ( void *  arg) [static]

Definition at line 238 of file tst-cancel4.c.

{
  int fd;
  int r;

  if (arg == NULL)
    fd = fds[1];
  else
    {
      char fname[] = "/tmp/tst-cancel4-fd-XXXXXX";
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
       printf ("%s: mkstemp failed\n", __FUNCTION__);
      unlink (fname);

      r = pthread_barrier_wait (&b2);
      if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
       {
         printf ("%s: barrier_wait failed\n", __FUNCTION__);
         exit (1);
       }
    }

  r = pthread_barrier_wait (&b2);
  if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
    {
      printf ("%s: barrier_wait failed\n", __FUNCTION__);
      exit (1);
    }

  ssize_t s;
  pthread_cleanup_push (cl, NULL);

  char buf[WRITE_BUFFER_SIZE];
  memset (buf, '\0', sizeof (buf));
  struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
  s = writev (fd, iov, 1);

  pthread_cleanup_pop (0);

  printf ("%s: writev returns with %zd\n", __FUNCTION__, s);

  exit (1);
}

Here is the call graph for this function:


Variable Documentation

pthread_barrier_t b2 [static]

Definition at line 80 of file tst-cancel4.c.

int cl_called [static]

Definition at line 90 of file tst-cancel4.c.

int fds[2] [static]

Definition at line 69 of file tst-cancel4.c.

int tempfd = -1 [static]

Definition at line 72 of file tst-cancel4.c.

int tempfd2 = -1 [static]

Definition at line 73 of file tst-cancel4.c.

char* tempfname [static]

Definition at line 75 of file tst-cancel4.c.

int tempmsg = -1 [static]

Definition at line 77 of file tst-cancel4.c.

struct { ... } tests[] [static]