]>
Commit | Line | Data |
---|---|---|
59c900c5 | 1 | /* Basic tests for SYSV message queue functions. |
04277e02 | 2 | Copyright (C) 2016-2019 Free Software Foundation, Inc. |
59c900c5 AZ |
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 | <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include <stdio.h> | |
20 | #include <stdlib.h> | |
21 | #include <errno.h> | |
22 | #include <string.h> | |
23 | #include <sys/types.h> | |
24 | #include <sys/ipc.h> | |
25 | #include <sys/msg.h> | |
26 | ||
27 | #include <support/support.h> | |
28 | #include <support/check.h> | |
29 | #include <support/temp_file.h> | |
30 | ||
31 | #define TEXTSIZE 32 | |
32 | struct msgbuf_t | |
33 | { | |
34 | #ifdef _GNU_SOURCE | |
35 | __syscall_slong_t type; | |
36 | #else | |
37 | long type; | |
38 | #endif | |
39 | char buf[TEXTSIZE]; | |
40 | }; | |
41 | ||
42 | #define MSGTYPE 0x01020304 | |
43 | #define MSGDATA "0123456789" | |
44 | ||
45 | /* These are for the temporary file we generate. */ | |
46 | static char *name; | |
47 | static int msqid; | |
48 | ||
49 | static void | |
50 | remove_msq (void) | |
51 | { | |
52 | /* Enforce message queue removal in case of early test failure. | |
53 | Ignore error since the msgq may already have being removed. */ | |
54 | msgctl (msqid, IPC_RMID, NULL); | |
55 | } | |
56 | ||
57 | static void | |
58 | do_prepare (int argc, char *argv[]) | |
59 | { | |
60 | int fd = create_temp_file ("tst-sysvmsg.", &name); | |
61 | if (fd == -1) | |
62 | FAIL_EXIT1 ("cannot create temporary file (errno=%d)", errno); | |
63 | } | |
64 | ||
65 | #define PREPARE do_prepare | |
66 | ||
67 | /* It is not an extensive test, but rather a functional one aimed to check | |
68 | correct parameter passing on kernel. */ | |
69 | ||
70 | #define MSGQ_MODE 0644 | |
71 | ||
72 | static int | |
73 | do_test (void) | |
74 | { | |
75 | atexit (remove_msq); | |
76 | ||
77 | key_t key = ftok (name, 'G'); | |
78 | if (key == -1) | |
79 | FAIL_EXIT1 ("ftok failed"); | |
80 | ||
81 | msqid = msgget (key, MSGQ_MODE | IPC_CREAT); | |
82 | if (msqid == -1) | |
83 | { | |
84 | if (errno == ENOSYS) | |
85 | FAIL_UNSUPPORTED ("msgget not supported"); | |
86 | FAIL_EXIT1 ("msgget failed (errno=%d)", errno); | |
87 | } | |
88 | ||
89 | /* Get message queue kernel information and do some sanity checks. */ | |
90 | struct msqid_ds msginfo; | |
91 | if (msgctl (msqid, IPC_STAT, &msginfo) == -1) | |
92 | FAIL_EXIT1 ("msgctl with IPC_STAT failed (errno=%d)", errno); | |
93 | ||
94 | if (msginfo.msg_perm.__key != key) | |
95 | FAIL_EXIT1 ("msgid_ds::msg_perm::key (%d) != %d", | |
96 | (int) msginfo.msg_perm.__key, (int) key); | |
97 | if (msginfo.msg_perm.mode != MSGQ_MODE) | |
98 | FAIL_EXIT1 ("msgid_ds::msg_perm::mode (%o) != %o", | |
99 | msginfo.msg_perm.mode, MSGQ_MODE); | |
100 | if (msginfo.msg_qnum != 0) | |
101 | FAIL_EXIT1 ("msgid_ds::msg_qnum (%lu) != 0", | |
102 | (long unsigned) msginfo.msg_qnum); | |
103 | ||
104 | /* Check if last argument (IPC_NOWAIT) is correctly handled. */ | |
105 | struct msgbuf_t msg2rcv = { 0 }; | |
106 | if (msgrcv (msqid, &msg2rcv, sizeof (msg2rcv.buf), MSGTYPE, | |
107 | IPC_NOWAIT) == -1 | |
108 | && errno != ENOMSG) | |
109 | FAIL_EXIT1 ("msgrcv failed (errno=%d)", errno); | |
110 | ||
111 | struct msgbuf_t msg2snd = { MSGTYPE, MSGDATA }; | |
112 | if (msgsnd (msqid, &msg2snd, sizeof (msg2snd.buf), 0) == -1) | |
113 | FAIL_EXIT1 ("msgsnd failed (errno=%d)", errno); | |
114 | ||
115 | if (msgrcv (msqid, &msg2rcv, sizeof (msg2rcv.buf), MSGTYPE, 0) == -1) | |
116 | FAIL_EXIT1 ("msgrcv failed (errno=%d)", errno); | |
117 | ||
118 | int ret = 0; | |
119 | if (strncmp (msg2snd.buf, msg2rcv.buf, TEXTSIZE) != 0) | |
120 | ret = 1; | |
121 | ||
122 | if (msgctl (msqid, IPC_RMID, NULL) == -1) | |
123 | FAIL_EXIT1 ("msgctl failed"); | |
124 | ||
125 | return ret; | |
126 | } | |
127 | ||
128 | #include <support/test-driver.c> |