1 /*
2 * Copyright (c) 2002-2003, Intel Corporation. All rights reserved.
3 * Created by: salwan.searty REMOVE-THIS AT intel DOT com
4 * This file is licensed under the GPL license. For the full content
5 * of this license, see the COPYING file at the top level of this
6 * source tree.
7 *
8 * Updated: 21.06.2011 Peter W. Morreale <pmorreale@novell.com>
9 *
10 * Steps:
11 * - Register for myhandler to be called when SIGTOTEST is called, and make
12 * sure SA_SIGINFO is set.
13 * - Block signal SIGTOTEST from the process.
14 * - Using sysconf(), check to see if there is a limit on number of queued
15 * signals that are pending. If there isn't a limit (i.e. sysconf returned
16 * -1), then this test is not applicable to the system's implementation,
17 * and thus we should pass it.
18 * - Using sigqueue(), send to the current process a number of instances
19 * (of SIGTOTEST) equal to the limit that sysconf() returned.
20 * - Send one more instance of SIGTOTEST and verify that sigqueue returns
21 * -1 and sets errno to [EAGAIN]
22 *
23 */
24
25 #define SIGTOTEST SIGRTMIN
26
27 #include <signal.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <pwd.h>
35 #include "posixtest.h"
36
37 #define MAX_ATTEMPTS 10000
38
reset_uid(void)39 static int reset_uid(void)
40 {
41 uid_t uid;
42
43 if (getuid())
44 return 0;
45
46 /* Search for an unused uid */
47 for (uid = 0; uid < MAX_ATTEMPTS; uid++) {
48 if (!getpwuid(uid) && !setuid(uid))
49 return 0;
50 }
51
52 printf("Failed: No unused uid's in %d attempts\n", MAX_ATTEMPTS);
53 return -1;
54 }
55
main(void)56 int main(void)
57 {
58 int pid = getpid();
59 int i;
60 long syslimit;
61 int rc;
62 union sigval value;
63
64 value.sival_int = 0; /* 0 is just an arbitrary value */
65 pid = getpid();
66
67 sighold(SIGTOTEST);
68
69 rc = reset_uid();
70 if (rc)
71 return PTS_UNRESOLVED;
72
73 /*
74 * Get system limit. Note that this limit is optional.
75 */
76 syslimit = sysconf(_SC_SIGQUEUE_MAX);
77 if (syslimit < 0)
78 goto done;
79
80 for (i = 0; i < syslimit; i++) {
81 if (sigqueue(pid, SIGTOTEST, value) != 0) {
82 printf("Failed: sigqueue on %d of %ld max, errno: %s\n",
83 i, syslimit, strerror(errno));
84 return PTS_UNRESOLVED;
85 }
86 }
87
88 /*
89 * Enqueue one more, needs to fail with EAGAIN
90 */
91 rc = sigqueue(pid, SIGTOTEST, value);
92 if (!(rc == -1 && errno == EAGAIN)) {
93 printf("Failed: sigqueue() queued SIGQUEUE_MAX+1 signals\n");
94 return PTS_FAIL;
95 }
96
97 done:
98 printf("Test PASSED\n");
99
100 return PTS_PASS;
101 }
102