• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 _XOPEN_SOURCE 600
26 #define SIGTOTEST SIGRTMIN
27 
28 #include <signal.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <pwd.h>
36 #include "posixtest.h"
37 
38 #define MAX_ATTEMPTS	10000
39 
reset_uid(void)40 static int reset_uid(void)
41 {
42 	uid_t uid;
43 
44 	if (getuid())
45 		return 0;
46 
47 	/* Search for an unused uid */
48 	for (uid = 0; uid < MAX_ATTEMPTS; uid++) {
49 		if (!getpwuid(uid) && !setuid(uid))
50 			return 0;
51 	}
52 
53 	printf("Failed: No unused uid's in %d attempts\n", MAX_ATTEMPTS);
54 	return -1;
55 }
56 
main(void)57 int main(void)
58 {
59 	int pid = getpid();
60 	int i;
61 	long syslimit;
62 	int rc;
63 	union sigval value;
64 
65 	value.sival_int = 0;	/* 0 is just an arbitrary value */
66 	pid = getpid();
67 
68 	sighold(SIGTOTEST);
69 
70 	rc = reset_uid();
71 	if (rc)
72 		return PTS_UNRESOLVED;
73 
74 	/*
75 	 * Get system limit.  Note that this limit is optional.
76 	 */
77 	syslimit = sysconf(_SC_SIGQUEUE_MAX);
78 	if (syslimit < 0)
79 		goto done;
80 
81 	for (i = 0; i < syslimit; i++) {
82 		if (sigqueue(pid, SIGTOTEST, value) != 0) {
83 			printf("Failed: sigqueue on %d of %d max, errno: %s\n",
84 			       i, syslimit, strerror(errno));
85 			return PTS_UNRESOLVED;
86 		}
87 	}
88 
89 	/*
90 	 * Enqueue one more, needs to fail with EAGAIN
91 	 */
92 	rc = sigqueue(pid, SIGTOTEST, value);
93 	if (!(rc == -1 && errno == EAGAIN)) {
94 		printf("Failed: sigqueue() queued SIGQUEUE_MAX+1 signals\n");
95 		return PTS_FAIL;
96 	}
97 
98 done:
99 	printf("Test PASSED\n");
100 
101 	return PTS_PASS;
102 }
103