Back to index

glibc  2.9
tst-mqueue2.c
Go to the documentation of this file.
00001 /* Test message queue passing.
00002    Copyright (C) 2004 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <mqueue.h>
00024 #include <signal.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <sys/time.h>
00029 #include <sys/wait.h>
00030 #include <time.h>
00031 #include <unistd.h>
00032 #include "tst-mqueue.h"
00033 
00034 static void
00035 alrm_handler (int sig)
00036 {
00037 }
00038 
00039 #define TIMEOUT 10
00040 #define TEST_FUNCTION do_test ()
00041 static int
00042 do_test (void)
00043 {
00044   int result = 0;
00045 
00046   char name[sizeof "/tst-mqueue2-" + sizeof (pid_t) * 3];
00047   snprintf (name, sizeof (name), "/tst-mqueue2-%u", getpid ());
00048 
00049   struct mq_attr attr = { .mq_maxmsg = 2, .mq_msgsize = 2 };
00050   mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
00051 
00052   if (q == (mqd_t) -1)
00053     {
00054       printf ("mq_open failed with: %m\n");
00055       return result;
00056     }
00057   else
00058     add_temp_mq (name);
00059 
00060   mqd_t q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
00061   if (q2 != (mqd_t) -1)
00062     {
00063       puts ("mq_open with O_EXCL unexpectedly succeeded");
00064       result = 1;
00065     }
00066   else if (errno != EEXIST)
00067     {
00068       printf ("mq_open did not fail with EEXIST: %m\n");
00069       result = 1;
00070     }
00071 
00072   char name2[sizeof "/tst-mqueue2-2-" + sizeof (pid_t) * 3];
00073   snprintf (name2, sizeof (name2), "/tst-mqueue2-2-%u", getpid ());
00074 
00075   attr.mq_maxmsg = -2;
00076   q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
00077   if (q2 != (mqd_t) -1)
00078     {
00079       puts ("mq_open with invalid mq_maxmsg unexpectedly succeeded");
00080       add_temp_mq (name2);
00081       result = 1;
00082     }
00083   else if (errno != EINVAL)
00084     {
00085       printf ("mq_open with invalid mq_maxmsg did not fail with "
00086              "EINVAL: %m\n");
00087       result = 1;
00088     }
00089 
00090   attr.mq_maxmsg = 2;
00091   attr.mq_msgsize = -56;
00092   q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
00093   if (q2 != (mqd_t) -1)
00094     {
00095       puts ("mq_open with invalid mq_msgsize unexpectedly succeeded");
00096       add_temp_mq (name2);
00097       result = 1;
00098     }
00099   else if (errno != EINVAL)
00100     {
00101       printf ("mq_open with invalid mq_msgsize did not fail with "
00102              "EINVAL: %m\n");
00103       result = 1;
00104     }
00105 
00106   char buf[3];
00107   struct timespec ts;
00108   if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
00109     ts.tv_sec += 10;
00110   else
00111     {
00112       ts.tv_sec = time (NULL) + 10;
00113       ts.tv_nsec = 0;
00114     }
00115 
00116   if (mq_timedreceive (q, buf, 1, NULL, &ts) == 0)
00117     {
00118       puts ("mq_timedreceive with too small msg_len did not fail");
00119       result = 1;
00120     }
00121   else if (errno != EMSGSIZE)
00122     {
00123       printf ("mq_timedreceive with too small msg_len did not fail with "
00124              "EMSGSIZE: %m\n");
00125       result = 1;
00126     }
00127 
00128   ts.tv_nsec = -1;
00129   if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
00130     {
00131       puts ("mq_timedreceive with negative tv_nsec did not fail");
00132       result = 1;
00133     }
00134   else if (errno != EINVAL)
00135     {
00136       printf ("mq_timedreceive with negative tv_nsec did not fail with "
00137              "EINVAL: %m\n");
00138       result = 1;
00139     }
00140 
00141   ts.tv_nsec = 1000000000;
00142   if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
00143     {
00144       puts ("mq_timedreceive with tv_nsec >= 1000000000 did not fail");
00145       result = 1;
00146     }
00147   else if (errno != EINVAL)
00148     {
00149       printf ("mq_timedreceive with tv_nsec >= 1000000000 did not fail with "
00150              "EINVAL: %m\n");
00151       result = 1;
00152     }
00153 
00154   struct sigaction sa = { .sa_handler = alrm_handler, .sa_flags = 0 };
00155   sigemptyset (&sa.sa_mask);
00156   sigaction (SIGALRM, &sa, NULL);
00157 
00158   struct itimerval it = { .it_value = { .tv_sec = 1 } };
00159   setitimer (ITIMER_REAL, &it, NULL);
00160 
00161   if (mq_receive (q, buf, 2, NULL) == 0)
00162     {
00163       puts ("mq_receive on empty queue did not block");
00164       result = 1;
00165     }
00166   else if (errno != EINTR)
00167     {
00168       printf ("mq_receive on empty queue did not fail with EINTR: %m\n");
00169       result = 1;
00170     }
00171 
00172   setitimer (ITIMER_REAL, &it, NULL);
00173 
00174   ts.tv_nsec = 0;
00175   if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
00176     {
00177       puts ("mq_timedreceive on empty queue did not block");
00178       result = 1;
00179     }
00180   else if (errno != EINTR)
00181     {
00182       printf ("mq_timedreceive on empty queue did not fail with EINTR: %m\n");
00183       result = 1;
00184     }
00185 
00186   buf[0] = '6';
00187   buf[1] = '7';
00188   if (mq_send (q, buf, 2, 3) != 0
00189       || (buf[0] = '8', mq_send (q, buf, 1, 4) != 0))
00190     {
00191       printf ("mq_send failed: %m\n");
00192       result = 1;
00193     }
00194 
00195   memset (buf, ' ', sizeof (buf));
00196 
00197   unsigned int prio;
00198   ssize_t rets = mq_receive (q, buf, 3, &prio);
00199   if (rets != 1)
00200     {
00201       if (rets == -1)
00202        printf ("mq_receive failed: %m\n");
00203       else
00204        printf ("mq_receive returned %zd != 1\n", rets);
00205       result = 1;
00206     }
00207   else if (prio != 4 || memcmp (buf, "8  ", 3) != 0)
00208     {
00209       printf ("mq_receive prio %u (4) buf \"%c%c%c\" (\"8  \")\n",
00210              prio, buf[0], buf[1], buf[2]);
00211       result = 1;
00212     }
00213 
00214   rets = mq_receive (q, buf, 2, NULL);
00215   if (rets != 2)
00216     {
00217       if (rets == -1)
00218        printf ("mq_receive failed: %m\n");
00219       else
00220        printf ("mq_receive returned %zd != 2\n", rets);
00221       result = 1;
00222     }
00223   else if (memcmp (buf, "67 ", 3) != 0)
00224     {
00225       printf ("mq_receive buf \"%c%c%c\" != \"67 \"\n",
00226              buf[0], buf[1], buf[2]);
00227       result = 1;
00228     }
00229 
00230   buf[0] = '2';
00231   buf[1] = '1';
00232   if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
00233     ts.tv_sec = time (NULL);
00234   ts.tv_nsec = -1000000001;
00235   if ((mq_timedsend (q, buf, 2, 5, &ts) != 0
00236        && (errno != EINVAL || mq_send (q, buf, 2, 5) != 0))
00237       || (buf[0] = '3', ts.tv_nsec = -ts.tv_nsec,
00238          (mq_timedsend (q, buf, 1, 4, &ts) != 0
00239           && (errno != EINVAL || mq_send (q, buf, 1, 4) != 0))))
00240     {
00241       printf ("mq_timedsend failed: %m\n");
00242       result = 1;
00243     }
00244 
00245   buf[0] = '-';
00246   ts.tv_nsec = 1000000001;
00247   if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
00248     {
00249       puts ("mq_timedsend with tv_nsec >= 1000000000 did not fail");
00250       result = 1;
00251     }
00252   else if (errno != EINVAL)
00253     {
00254       printf ("mq_timedsend with tv_nsec >= 1000000000 did not fail with "
00255              "EINVAL: %m\n");
00256       result = 1;
00257     }
00258 
00259   ts.tv_nsec = -2;
00260   if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
00261     {
00262       puts ("mq_timedsend with negative tv_nsec did not fail");
00263       result = 1;
00264     }
00265   else if (errno != EINVAL)
00266     {
00267       printf ("mq_timedsend with megatove tv_nsec did not fail with "
00268              "EINVAL: %m\n");
00269       result = 1;
00270     }
00271 
00272   setitimer (ITIMER_REAL, &it, NULL);
00273 
00274   if (mq_send (q, buf, 2, 8) == 0)
00275     {
00276       puts ("mq_send on full queue did not block");
00277       result = 1;
00278     }
00279   else if (errno != EINTR)
00280     {
00281       printf ("mq_send on full queue did not fail with EINTR: %m\n");
00282       result = 1;
00283     }
00284 
00285   setitimer (ITIMER_REAL, &it, NULL);
00286 
00287   ts.tv_sec += 10;
00288   ts.tv_nsec = 0;
00289   if (mq_timedsend (q, buf, 2, 7, &ts) == 0)
00290     {
00291       puts ("mq_timedsend on full queue did not block");
00292       result = 1;
00293     }
00294   else if (errno != EINTR)
00295     {
00296       printf ("mq_timedsend on full queue did not fail with EINTR: %m\n");
00297       result = 1;
00298     }
00299 
00300   memset (buf, ' ', sizeof (buf));
00301 
00302   if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
00303     ts.tv_sec = time (NULL);
00304   ts.tv_nsec = -1000000001;
00305   rets = mq_timedreceive (q, buf, 2, &prio, &ts);
00306   if (rets == -1 && errno == EINVAL)
00307     rets = mq_receive (q, buf, 2, &prio);
00308   if (rets != 2)
00309     {
00310       if (rets == -1)
00311        printf ("mq_timedreceive failed: %m\n");
00312       else
00313        printf ("mq_timedreceive returned %zd != 2\n", rets);
00314       result = 1;
00315     }
00316   else if (prio != 5 || memcmp (buf, "21 ", 3) != 0)
00317     {
00318       printf ("mq_timedreceive prio %u (5) buf \"%c%c%c\" (\"21 \")\n",
00319              prio, buf[0], buf[1], buf[2]);
00320       result = 1;
00321     }
00322 
00323   if (mq_receive (q, buf, 1, NULL) == 0)
00324     {
00325       puts ("mq_receive with too small msg_len did not fail");
00326       result = 1;
00327     }
00328   else if (errno != EMSGSIZE)
00329     {
00330       printf ("mq_receive with too small msg_len did not fail with "
00331              "EMSGSIZE: %m\n");
00332       result = 1;
00333     }
00334 
00335   ts.tv_nsec = -ts.tv_nsec;
00336   rets = mq_timedreceive (q, buf, 2, NULL, &ts);
00337   if (rets == -1 && errno == EINVAL)
00338     rets = mq_receive (q, buf, 2, NULL);
00339   if (rets != 1)
00340     {
00341       if (rets == -1)
00342        printf ("mq_timedreceive failed: %m\n");
00343       else
00344        printf ("mq_timedreceive returned %zd != 1\n", rets);
00345       result = 1;
00346     }
00347   else if (memcmp (buf, "31 ", 3) != 0)
00348     {
00349       printf ("mq_timedreceive buf \"%c%c%c\" != \"31 \"\n",
00350              buf[0], buf[1], buf[2]);
00351       result = 1;
00352     }
00353 
00354   if (mq_send (q, "", 0, 2) != 0)
00355     {
00356       printf ("mq_send with msg_len 0 failed: %m\n");
00357       result = 1;
00358     }
00359 
00360   rets = mq_receive (q, buf, 2, &prio);
00361   if (rets)
00362     {
00363       if (rets == -1)
00364        printf ("mq_receive failed: %m\n");
00365       else
00366        printf ("mq_receive returned %zd != 0\n", rets);
00367       result = 1;
00368     }
00369 
00370   long mq_prio_max = sysconf (_SC_MQ_PRIO_MAX);
00371   if (mq_prio_max > 0 && (unsigned int) mq_prio_max == mq_prio_max)
00372     {
00373       if (mq_send (q, buf, 1, mq_prio_max) == 0)
00374        {
00375          puts ("mq_send with MQ_PRIO_MAX priority unpexpectedly succeeded");
00376          result = 1;
00377        }
00378       else if (errno != EINVAL)
00379        {
00380          printf ("mq_send with MQ_PRIO_MAX priority did not fail with "
00381                 "EINVAL: %m\n");
00382          result = 1;
00383        }
00384 
00385       if (mq_send (q, buf, 1, mq_prio_max - 1) != 0)
00386        {
00387          printf ("mq_send with MQ_PRIO_MAX-1 priority failed: %m\n");
00388          result = 1;
00389        }
00390     }
00391 
00392   if (mq_unlink (name) != 0)
00393     {
00394       printf ("mq_unlink failed: %m\n");
00395       result = 1;
00396     }
00397 
00398   q2 = mq_open (name, O_RDWR);
00399   if (q2 != (mqd_t) -1)
00400     {
00401       printf ("mq_open of unlinked %s without O_CREAT unexpectedly"
00402              "succeeded\n", name);
00403       result = 1;
00404     }
00405   else if (errno != ENOENT)
00406     {
00407       printf ("mq_open of unlinked %s without O_CREAT did not fail with "
00408              "ENOENT: %m\n", name);
00409       result = 1;
00410     }
00411 
00412   if (mq_close (q) != 0)
00413     {
00414       printf ("mq_close in parent failed: %m\n");
00415       result = 1;
00416     }
00417 
00418   if (mq_receive (q, buf, 2, NULL) == 0)
00419     {
00420       puts ("mq_receive on invalid mqd_t did not fail");
00421       result = 1;
00422     }
00423   else if (errno != EBADF)
00424     {
00425       printf ("mq_receive on invalid mqd_t did not fail with EBADF: %m\n");
00426       result = 1;
00427     }
00428 
00429   if (mq_send (q, buf, 1, 2) == 0)
00430     {
00431       puts ("mq_send on invalid mqd_t did not fail");
00432       result = 1;
00433     }
00434   else if (errno != EBADF)
00435     {
00436       printf ("mq_send on invalid mqd_t did not fail with EBADF: %m\n");
00437       result = 1;
00438     }
00439 
00440   if (mq_getattr (q, &attr) == 0)
00441     {
00442       puts ("mq_getattr on invalid mqd_t did not fail");
00443       result = 1;
00444     }
00445   else if (errno != EBADF)
00446     {
00447       printf ("mq_getattr on invalid mqd_t did not fail with EBADF: %m\n");
00448       result = 1;
00449     }
00450 
00451   memset (&attr, 0, sizeof (attr));
00452   if (mq_setattr (q, &attr, NULL) == 0)
00453     {
00454       puts ("mq_setattr on invalid mqd_t did not fail");
00455       result = 1;
00456     }
00457   else if (errno != EBADF)
00458     {
00459       printf ("mq_setattr on invalid mqd_t did not fail with EBADF: %m\n");
00460       result = 1;
00461     }
00462 
00463   if (mq_unlink ("/tst-mqueue2-which-should-never-exist") != -1)
00464     {
00465       puts ("mq_unlink of non-existant message queue unexpectedly succeeded");
00466       result = 1;
00467     }
00468   else if (errno != ENOENT)
00469     {
00470       printf ("mq_unlink of non-existant message queue did not fail with "
00471              "ENOENT: %m\n");
00472       result = 1;
00473     }
00474   return result;
00475 }
00476 
00477 #include "../test-skeleton.c"