Initial import of t_shmat.
[pcca-tests.git] / mqueue.h / t_mq_open_umask.c
1 /*
2  * Copyright (c) 2009, Stathis Kamperis
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
18  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
24  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <assert.h>
29 #include <errno.h>
30 #include <mqueue.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <sys/stat.h>
35 #include <sys/wait.h>
36
37 #define MQNAME  "/t_mq_open_umask"
38
39 int
40 main(void)
41 {
42         /*
43          * Set the file creation mask to u=rwx g=rwx o=rwx.
44          *
45          * We will check later on, if it is honoured during the creation
46          * of a new message queue.
47          */
48         umask(0777);
49         assert(umask(0777) == 0777);    /* Paranoia */
50
51         /*
52          * Create the message queue with permission bits set to 777.
53          *
54          * But since the file creation mask is already 777, the queue should be
55          * created with 000.
56          */
57         mqd_t md;
58
59         md = mq_open(MQNAME, O_CREAT | O_EXCL | O_RDWR, 0777, NULL);
60         assert(md != (mqd_t)-1);
61
62         /* Disassociate from the message queue. */
63         assert(mq_close(md) != -1);
64
65         /* Fork! */
66         pid_t pid = fork();
67         assert(pid != -1);
68
69         if (pid == 0) {
70                 /* We are inside the child. */
71
72                 /*
73                  * The file creation mask isn't inherited by the child process
74                  * during fork(), but we will set it to 000 anyway as we don't
75                  * want it to interfere with our modes.
76                  */
77                 umask(0);
78                 assert(umask(0) == 0);  /* Paranoia */
79
80                 mode_t modes[] = { 000, 001, 002, 004,  /* XXX: What about 000 ? */
81                                    010, 012, 011, 014,
82                                    020, 021, 022, 024,
83                                    040, 041, 042, 044,
84
85                                    100, 101, 102, 104,
86                                    110, 111, 112, 114,
87                                    120, 121, 122, 124,
88                                    140, 141, 142, 144,
89
90                                    200, 201, 202, 204,
91                                    210, 211, 212, 214,
92                                    220, 221, 222, 224,
93                                    240, 241, 242, 244,
94
95                                    400, 401, 402, 404,
96                                    410, 411, 412, 414,
97                                    420, 421, 422, 424,
98                                    440, 441, 442, 444
99
100                                    /*
101                                     * We expect or rather hope that the combined
102                                     * permission bits, e.g. 777, are covered by
103                                     * the above fundamental set.
104                                     */
105                 };
106
107                 size_t i;
108                 for (i = 0; i < sizeof(modes) / sizeof(*modes); i++)
109                   assert(mq_open(MQNAME, O_CREAT, modes[i], NULL) == (mqd_t)-1
110                             && errno == EACCES);
111
112                 /* Remove the message queue from the system. */
113                 assert(mq_unlink(MQNAME) != -1);
114         } else {
115                 /* We are inside the parent. */
116
117                 /* Wait for child to complete. */
118                 int status;
119                 assert(wait(&status) == pid);
120
121                 /*
122                  * Determine if the child exited normally, or due to a SIGABRT
123                  * signal being delivered to it by a failed assertion.
124                  */
125                 if (WIFSIGNALED(status)) {
126                         assert(WTERMSIG(status) == SIGABRT);
127                         return (EXIT_FAILURE);
128                 } else {
129                         printf("passed\n");
130
131                         return (EXIT_SUCCESS);
132                 }
133         }
134
135         /* Only reached by child upon success. */
136         return (EXIT_SUCCESS);
137 }