Fix sigpending handling in sigqueue (9-1), by checking current pendings from /proc/<pid>/status -> SigQ. Also, added new functionality, check that purged signals received correctly.
Signed-off-by: Hannu Heikkinen <[email protected]> --- .../conformance/interfaces/sigqueue/9-1.c | 183 +++++++++++++++++--- 1 files changed, 160 insertions(+), 23 deletions(-) diff --git a/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/9-1.c b/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/9-1.c index e8592d5..fa8ad20 100644 --- a/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/9-1.c +++ b/testcases/open_posix_testsuite/conformance/interfaces/sigqueue/9-1.c @@ -24,63 +24,200 @@ #define SIGTOTEST SIGRTMIN #define NUMCALLS 5 +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> #include <signal.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> +#include <string.h> #include <errno.h> #include "posixtest.h" -void myhandler(int signo, siginfo_t *info, void *context) { - printf ("Inside Handler\n"); +static long purged = 0; + +void myhandler(int signo, siginfo_t *info, void *context) +{ + purged++; } -int main() +int get_proc_sig(int pid, long *current_sig, long *max_sig) { + int f; + char procdir[128]=""; + char line[1024]=""; + char *pos, *pos2; + char *sig; + char c; + long curr, max; + int len; + int ret; - int pid, i; - long syslimit; - union sigval value; + snprintf(procdir, sizeof(procdir)-1, "/proc/%d/status", pid); + procdir[sizeof(procdir)-1] = '\0'; + + f = open(procdir, O_RDONLY); + if (f == -1) + return -1; + + len = read(f, line, sizeof(line)-1); + close(f); + + if (len <= 0) + return -1; + else + line[len] = '\0'; + + pos = strstr(line, "SigQ:"); + if (pos == NULL) + return -1; + + pos2 = strchr(pos, '\n'); + if (pos2 == NULL) + return -1; + + sig = pos; + sig[pos2-pos] = '\0'; + sig = strrchr(sig, '\t'); + if (sig == NULL) + return -1; + + printf("%s: from proc: %s\n", __func__, sig); + if ((ret = sscanf(sig, "%ld%c%ld", &curr, &c, &max)) != 3) { + printf("%s: Matching only %d items...\n", + __func__, ret); + return -1; + } + printf("%s: %s -> matched: %ld%c%ld\n", + __func__, sig, curr, c, max); + + *current_sig = curr; + *max_sig = max; + + return 0; +} + +int set_signals(sigset_t *new, sigset_t *old) +{ struct sigaction act; + sigset_t new_set, old_set; act.sa_flags = SA_SIGINFO; act.sa_sigaction = myhandler; sigemptyset(&act.sa_mask); sigaction(SIGTOTEST, &act, 0); - value.sival_int = 0; /* 0 is just an arbitrary value */ - pid = getpid(); + printf("SIGRTMIN signals blocked\n"); + sigemptyset(&new_set); + sigaddset(&new_set, SIGTOTEST); + sigprocmask(SIG_BLOCK, &new_set, &old_set); + *old = old_set; + *new = new_set; - sighold(SIGTOTEST); + return 0; +} - syslimit = sysconf(_SC_SIGQUEUE_MAX); +int do_purge_test(sigset_t old, long syslimit) +{ + int sanity = 12; - printf("sigqueuemax %ld\n", syslimit); - - if (syslimit == -1) { - printf("Test PASSED: Actually, test is not applicable to this implementation. This system has no defined limit." - " Note: it is optional whether an implementation has this limit, so this is" - " not a bug.\n"); - return PTS_PASS; + printf("SIGRTMIN signals unblocked\n"); + sigprocmask(SIG_SETMASK, &old, NULL); + + while (purged < syslimit && sanity > 0) { + sleep(1); + sanity--; } - for (i=0; i<syslimit; i++) { - if (sigqueue(pid, SIGTOTEST, value) != 0) { - printf("Test UNRESOLVED: call to sigqueue did not return success\n"); + return purged; +} + +int do_queue_test(int pid, long syslimit) +{ + int ret; + int i; + union sigval value; + + value.sival_int = 0; /* 0 is just an arbitrary value */ + + for (i = 0; i < syslimit; i++) { + errno = 0; + if ((ret = sigqueue(pid, SIGTOTEST, value)) != 0) { + printf("Test UNRESOLVED: sigqueue ERROR: ret: %d errno: %d (%s), " + "sigqueues succeeded: %d, but syslimit: %d\n", + ret, + (int)errno, + strerror(errno), + i, + (int)syslimit); return PTS_UNRESOLVED; } } + errno = 0; if (sigqueue(pid, SIGTOTEST, value) != -1) { - printf("Test FAILED: sigqueue did not return -1 even though the process has already queued {SIGQUEUE_MAX} signals that are still pending.\n"); + printf("Test FAILED: sigqueue ERROR: ret: %d errno %d (%s). " + "sigqueue should return -1 because the process already queued signals, which are pending\n", + ret, + (int)errno, + strerror(errno)); return PTS_FAIL; } - + if (errno != EAGAIN) { - printf("Test FAILED: errno was not set to [EAGAIN] even though the process has already queued {SIGQUEUE_MAX} signals that are still pending.\n"); + printf("Test FAILED: errno was not set to [EAGAIN] even " + "though the process has already queued {SIGQUEUE_MAX} signals " + "that are still pending.\n"); } return PTS_PASS; } +int main() +{ + long syslimit; + long curr, max; + sigset_t new_set, old_set; + int ret = PTS_FAIL; + + syslimit = sysconf(_SC_SIGQUEUE_MAX); + printf("sigqueuemax %ld\n", syslimit); + + if (syslimit == -1) { + printf("Test PASSED: Actually, test is not applicable to this implementation." + " This system has no defined limit." + " Note: it is optional whether an implementation has this limit, so this is" + " not a bug.\n"); + return PTS_PASS; + } + + sleep(1); + if (get_proc_sig(getpid(), &curr, &max) == 0) { + if (curr >= syslimit) { + printf("Test UNRESOLVED: syslimit %ld less or equal to current pending %ld\n", + syslimit, curr); + return PTS_UNRESOLVED; + } + printf("reducing syslimit %ld -> %ld due to current pending %ld\n", + syslimit, + syslimit-curr, + curr); + syslimit -= curr; + } + set_signals(&new_set, &old_set); + ret = do_queue_test(getpid(), syslimit); + if (ret == PTS_PASS) { + int purged = do_purge_test(old_set, syslimit); + printf("Purged %d of %d pending signals, not-purged %d\n", + (int)purged, + (int)syslimit, + (int)(syslimit-purged)); + if (purged != syslimit) + return PTS_FAIL; + } + + return ret; +} -- 1.7.3 ------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Ltp-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/ltp-list
