Home | History | Annotate | Download | only in sigqueue
      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 (at) 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 
     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 
     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