(root)/
glibc-2.38/
rt/
tst-mqueue4.c
       1  /* Test message queue passing.
       2     Copyright (C) 2004-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <fcntl.h>
      21  #include <mqueue.h>
      22  #include <limits.h>
      23  #include <signal.h>
      24  #include <stdio.h>
      25  #include <stdint.h>
      26  #include <stdlib.h>
      27  #include <string.h>
      28  #include <sys/time.h>
      29  #include <sys/wait.h>
      30  #include <time.h>
      31  #include <unistd.h>
      32  #include <support/check.h>
      33  #include "tst-mqueue.h"
      34  
      35  #define TEST_FUNCTION do_test ()
      36  static int
      37  do_test (void)
      38  {
      39    int result = 0;
      40  
      41    char name[sizeof "/tst-mqueue4-" + sizeof (pid_t) * 3 + NAME_MAX];
      42    char *p;
      43    p = name + snprintf (name, sizeof (name), "/tst-mqueue4-%u", getpid ());
      44    struct mq_attr attr = { .mq_maxmsg = 2, .mq_msgsize = 2 };
      45    mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
      46  
      47    if (q == (mqd_t) -1)
      48      {
      49        if (errno == ENOSYS)
      50  	FAIL_UNSUPPORTED ("mq_open not supported");
      51  
      52        printf ("mq_open failed with: %m\n");
      53        return 1;
      54      }
      55  
      56    add_temp_mq (name);
      57  
      58    *p = '.';
      59    memset (p + 1, 'x', NAME_MAX + 1 - (p - name));
      60    name[NAME_MAX + 1] = '\0';
      61  
      62    mqd_t q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
      63    if (q2 == (mqd_t) -1)
      64      {
      65        printf ("mq_open with NAME_MAX long name component failed with: %m\n");
      66        result = 1;
      67      }
      68  
      69    if (mq_unlink (name) != 0)
      70      {
      71        printf ("mq_unlink failed: %m\n");
      72        result = 1;
      73      }
      74  
      75    if (mq_close (q2) != 0)
      76      {
      77        printf ("mq_close failed: %m\n");
      78        result = 1;
      79      }
      80  
      81    name[NAME_MAX + 1] = 'x';
      82    name[NAME_MAX + 2] = '\0';
      83    q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
      84    if (q2 != (mqd_t) -1)
      85      {
      86        puts ("mq_open with too long name component unexpectedly succeeded");
      87        mq_unlink (name);
      88        mq_close (q2);
      89        result = 1;
      90      }
      91    else if (errno != ENAMETOOLONG)
      92      {
      93        printf ("mq_open with too long name component did not fail with "
      94  	      "ENAMETOOLONG: %m\n");
      95        result = 1;
      96      }
      97  
      98    if (mq_unlink (name) == 0)
      99      {
     100        puts ("mq_unlink with too long name component unexpectedly succeeded");
     101        result = 1;
     102      }
     103    else if (errno != ENAMETOOLONG)
     104      {
     105        printf ("mq_unlink with too long name component did not fail with "
     106  	      "ENAMETOOLONG: %m\n");
     107        result = 1;
     108      }
     109  
     110    *p = '\0';
     111    attr.mq_maxmsg = 1;
     112    attr.mq_msgsize = 3;
     113    q2 = mq_open (name, O_CREAT | O_RDWR, 0600, &attr);
     114    if (q2 == (mqd_t) -1)
     115      {
     116        printf ("mq_open without O_EXCL failed with %m\n");
     117        result = 1;
     118      }
     119  
     120    char buf[3];
     121    strcpy (buf, "jk");
     122    if (mq_send (q, buf, 2, 4) != 0)
     123      {
     124        printf ("mq_send failed: %m\n");
     125        result = 1;
     126      }
     127  
     128    if (mq_send (q, buf + 1, 1, 5) != 0)
     129      {
     130        printf ("mq_send failed: %m\n");
     131        result = 1;
     132      }
     133  
     134    if (mq_getattr (q2, &attr) != 0)
     135      {
     136        printf ("mq_getattr failed: %m\n");
     137        result = 1;
     138      }
     139  
     140    if ((attr.mq_flags & O_NONBLOCK)
     141        || attr.mq_maxmsg != 2
     142        || attr.mq_msgsize != 2
     143        || attr.mq_curmsgs != 2)
     144      {
     145        printf ("mq_getattr returned unexpected { .mq_flags = %jd,\n"
     146  	      ".mq_maxmsg = %jd, .mq_msgsize = %jd, .mq_curmsgs = %jd }\n",
     147  	      (intmax_t) attr.mq_flags, (intmax_t) attr.mq_maxmsg,
     148  	      (intmax_t) attr.mq_msgsize, (intmax_t) attr.mq_curmsgs);
     149        result = 1;
     150      }
     151  
     152    struct timespec ts;
     153    if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
     154      ++ts.tv_sec;
     155    else
     156      {
     157        ts.tv_sec = time (NULL) + 1;
     158        ts.tv_nsec = 0;
     159      }
     160  
     161    if (mq_timedsend (q2, buf, 1, 1, &ts) == 0)
     162      {
     163        puts ("mq_timedsend unexpectedly succeeded");
     164        result = 1;
     165      }
     166    else if (errno != ETIMEDOUT)
     167      {
     168        printf ("mq_timedsend did not fail with ETIMEDOUT: %m\n");
     169        result = 1;
     170      }
     171  
     172    if (mq_close (q2) != 0)
     173      {
     174        printf ("mq_close failed: %m\n");
     175        result = 1;
     176      }
     177  
     178    q2 = mq_open (name, O_RDONLY);
     179    if (q2 == (mqd_t) -1)
     180      {
     181        printf ("mq_open without O_CREAT failed with %m\n");
     182        result = 1;
     183      }
     184  
     185    mqd_t q3 = mq_open (name, O_RDONLY);
     186    if (q3 == (mqd_t) -1)
     187      {
     188        printf ("mq_open without O_CREAT failed with %m\n");
     189        result = 1;
     190      }
     191  
     192    memset (buf, ' ', sizeof (buf));
     193  
     194    unsigned int prio;
     195    ssize_t rets = mq_receive (q2, buf, 2, &prio);
     196    if (rets != 1)
     197      {
     198        if (rets == -1)
     199  	printf ("mq_receive failed with: %m\n");
     200        else
     201  	printf ("mq_receive returned %zd != 1\n", rets);
     202        result = 1;
     203      }
     204    else if (prio != 5 || memcmp (buf, "k  ", 3) != 0)
     205      {
     206        printf ("mq_receive returned prio %u (2) buf \"%c%c%c\" (\"k  \")\n",
     207  	      prio, buf[0], buf[1], buf[2]);
     208        result = 1;
     209      }
     210  
     211    if (mq_getattr (q3, &attr) != 0)
     212      {
     213        printf ("mq_getattr failed: %m\n");
     214        result = 1;
     215      }
     216  
     217    if ((attr.mq_flags & O_NONBLOCK)
     218        || attr.mq_maxmsg != 2
     219        || attr.mq_msgsize != 2
     220        || attr.mq_curmsgs != 1)
     221      {
     222        printf ("mq_getattr returned unexpected { .mq_flags = %jd,\n"
     223  	      ".mq_maxmsg = %jd, .mq_msgsize = %jd, .mq_curmsgs = %jd }\n",
     224  	      (intmax_t) attr.mq_flags, (intmax_t) attr.mq_maxmsg,
     225  	      (intmax_t) attr.mq_msgsize, (intmax_t) attr.mq_curmsgs);
     226        result = 1;
     227      }
     228  
     229    rets = mq_receive (q3, buf, 2, NULL);
     230    if (rets != 2)
     231      {
     232        if (rets == -1)
     233  	printf ("mq_receive failed with: %m\n");
     234        else
     235  	printf ("mq_receive returned %zd != 2\n", rets);
     236        result = 1;
     237      }
     238    else if (memcmp (buf, "jk ", 3) != 0)
     239      {
     240        printf ("mq_receive returned buf \"%c%c%c\" != \"jk \"\n",
     241  	      buf[0], buf[1], buf[2]);
     242        result = 1;
     243      }
     244  
     245    if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
     246      ++ts.tv_sec;
     247    else
     248      {
     249        ts.tv_sec = time (NULL) + 1;
     250        ts.tv_nsec = 0;
     251      }
     252  
     253    if (mq_timedreceive (q2, buf, 2, NULL, &ts) != -1)
     254      {
     255        puts ("mq_timedreceive on empty queue unexpectedly succeeded");
     256        result = 1;
     257      }
     258    else if (errno != ETIMEDOUT)
     259      {
     260        printf ("mq_timedreceive on empty queue did not fail with "
     261  	      "ETIMEDOUT: %m\n");
     262        result = 1;
     263      }
     264  
     265    if (mq_unlink (name) != 0)
     266      {
     267        printf ("mq_unlink failed: %m\n");
     268        result = 1;
     269      }
     270  
     271    if (mq_close (q) != 0)
     272      {
     273        printf ("mq_close failed: %m\n");
     274        result = 1;
     275      }
     276  
     277    if (mq_close (q2) != 0)
     278      {
     279        printf ("mq_close failed: %m\n");
     280        result = 1;
     281      }
     282  
     283    if (mq_close (q3) != 0)
     284      {
     285        printf ("mq_close failed: %m\n");
     286        result = 1;
     287      }
     288  
     289    return result;
     290  }
     291  
     292  #include "../test-skeleton.c"