(root)/
glibc-2.38/
nptl/
tst-cancel4_1.c
       1  /* Check sendmmsg cancellation.
       2  
       3     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       4     This file is part of the GNU C Library.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  #include <stdio.h>
      21  #include <stddef.h>
      22  #include <stdlib.h>
      23  #include <string.h>
      24  #include <sys/types.h>
      25  #include <sys/socket.h>
      26  #include <sys/un.h>
      27  #include <sys/ipc.h>
      28  #include <sys/msg.h>
      29  #include <unistd.h>
      30  #include <errno.h>
      31  #include <pthread.h>
      32  
      33  #include "tst-cancel4-common.h"
      34  
      35  static void *
      36  tf_sendmmsg (void *arg)
      37  {
      38    if (arg == NULL)
      39      // XXX If somebody can provide a portable test case in which sendmmsg()
      40      // blocks we can enable this test to run in both rounds.
      41      abort ();
      42  
      43    struct sockaddr_un sun;
      44  
      45    tempfd = socket (AF_UNIX, SOCK_DGRAM, 0);
      46    if (tempfd == -1)
      47      FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
      48  
      49    int tries = 0;
      50    do
      51      {
      52        if (++tries > 10)
      53  	FAIL_EXIT1 ("too many unsuccessful bind calls");
      54  
      55        strcpy (sun.sun_path, "/tmp/tst-cancel4-socket-7-XXXXXX");
      56        if (mktemp (sun.sun_path) == NULL)
      57  	FAIL_EXIT1 ("cannot generate temp file name");
      58  
      59        sun.sun_family = AF_UNIX;
      60      }
      61    while (bind (tempfd, (struct sockaddr *) &sun,
      62  	       offsetof (struct sockaddr_un, sun_path)
      63  	       + strlen (sun.sun_path) + 1) != 0);
      64    tempfname = strdup (sun.sun_path);
      65  
      66    tempfd2 = socket (AF_UNIX, SOCK_DGRAM, 0);
      67    if (tempfd2 == -1)
      68      FAIL_EXIT1 ("socket (AF_UNIX, SOCK_DGRAM, 0): %m");
      69  
      70    int r = pthread_barrier_wait (&b2);
      71    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      72      FAIL_EXIT1 ("pthread_barrier_wait");
      73  
      74    r = pthread_barrier_wait (&b2);
      75    if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
      76      FAIL_EXIT1 ("pthread_barrier_wait");
      77  
      78    pthread_cleanup_push (cl, NULL);
      79  
      80    char mem[1];
      81    struct iovec iov[1];
      82    iov[0].iov_base = mem;
      83    iov[0].iov_len = 1;
      84  
      85    struct mmsghdr mm;
      86    mm.msg_hdr.msg_name = &sun;
      87    mm.msg_hdr.msg_namelen = (offsetof (struct sockaddr_un, sun_path)
      88  			   + strlen (sun.sun_path) + 1);
      89    mm.msg_hdr.msg_iov = iov;
      90    mm.msg_hdr.msg_iovlen = 1;
      91    mm.msg_hdr.msg_control = NULL;
      92    mm.msg_hdr.msg_controllen = 0;
      93  
      94    ssize_t ret = sendmmsg (tempfd2, &mm, 1, 0);
      95    if (ret == -1 && errno == ENOSYS)
      96      exit (77);
      97  
      98    pthread_cleanup_pop (0);
      99  
     100    FAIL_EXIT1 ("sendmmsg returned");
     101  }
     102  
     103  struct cancel_tests tests[] =
     104  {
     105    ADD_TEST (sendmmsg, 2, 1),
     106  };
     107  #define ntest_tf (sizeof (tests) / sizeof (tests[0]))
     108  
     109  #include "tst-cancel4-common.c"