This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

sigsuspend() returns 111 on Alpha (repeatable, w/ source)


Hi All,

My coworkers and I have found a case where sigsuspend() returns 111.  The
condition is repeatable using the code in this message.  This behavior
contradicts what is described in the manual page for sigsuspend().  According
to the manual page sigsuspend() should ALWAYS return -1; only errno should be
different.

The following highlights our configuration:

    o) Alpha ES40, I can provide more details if necessary.
    o) RedHat Linux 6.2.
    o) kernel 2.2.14 (RedHat package 2.2.14-6.0smp).
    o) glibc 2.1.3 (RedHat package 2.1.3-16).
    o) egcs 1.1.2 (RedHat package 1.1.2-30).

The program attached establishes a signal handler for SIGUSR2.  It enters a
while loop and calls sigsuspend().  It displays a message when the signal
handler is called and displays the return value of sigsuspend().

Depending on the location of the localtime(), the return value of sigsuspend()
will vary.  If localtime() is commented out, sigsuspend() will return 111.  If
localtime() is before the loop, sigsuspend() will return -1 the first time,
111 there after.  If localtime() is in the loop, sigsuspend() will always
return -1.  We found it odd that calling localtime() affected the return value
of sigsuspend :-)

For example:

viper% cc sigbug.c -o sigbug
viper% ./sigbug &
[2] 3691
viper% kill -USR2 %2
in sig handler, got sig 31
sigsuspend return is -1
viper% kill -USR2 %2
in sig handler, got sig 31
sigsuspend return is 111
viper% kill -USR2 %2
in sig handler, got sig 31
sigsuspend return is 111

Coincidentally, 111 corresponds to the syscall number for sigsuspend.

include/asm-alpha/unistd.h:#define __NR_sigsuspend              111

We ran the same source on an Intel/Linux box and the return value of
sigsuspend was always -1.

Eric Sorton <eric@cctcorp.com>
Command and Control Technologies

#include <stdio.h>      /* perror(), printf() */
#include <signal.h>     /* sigfillset(), sigaction(), sigemptyset(), sigaddset(), sigprocmask(), sigsuspend() */
#include <time.h>       /* time(), localtime() */

void SignalHandler(int sig) {
	printf("in sig handler, got sig %d\n", sig);
}

int main() {
	sigset_t allsigs;
	sigset_t blocksigs;
	struct sigaction act;
	int rtn;
	time_t t;
	struct tm *tp;

	sigfillset(&act.sa_mask);
	act.sa_handler = SignalHandler;
	act.sa_flags = 0;

	if (sigaction(SIGUSR2, &act, NULL) == -1) {
		perror("sigaction");
		return -1;
	}

	sigemptyset(&allsigs);
	sigemptyset(&blocksigs);

	if (sigaddset(&blocksigs, SIGUSR2) == -1) {
		perror("sigaddset");
		return -1;
	}

	if (sigprocmask(SIG_SETMASK, &blocksigs, NULL) == -1) {
		perror("sigprocmask");
		return -1;
	}

	t = time(NULL);

        /*
         * Comment/uncomment this line to change behavior of
         * the application.  If the line is commented out, then sending
         * SIGUSR2 to the process will cause the sigsuspend() below to return
         * with a 111.  If the line is uncommented, then sending SIGUSR2 to
         * the process will cause sigsuspend() below to return with a -1 the
         * first time, further SIGUSR2s will cause it to return with 111.
         */

	tp = localtime(&t);

	while (1) {
		rtn = sigsuspend(&allsigs);
		printf("sigsuspend return is %d\n", rtn);
	}

	return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]