Linux passes the arguments in registers, but our compiler expects arguments on the stack. Signal handlers got garbage instead of the signal number. Some handlers, like the one in lang/m2/libm2/sigtrp.c, need the correct signal number. I write a "bridge" in PowerPC assembly that moves the arguments to the stack. I put the bridge in sigaction(), so I provide a signal() that calls sigaction(). I remove the *.c glob or wildcard from build.lua, so linuxppc only compiles its own signal.c, not the other signal.c for linux386 and linux68k. My bridge uses sigprocmask(), so I also add sigprocmask(). Because linux386 and linux68k use globs, they also get sigprocmask(). I sync the header files so all three Linux platforms declare execve(), sigprocmask(), and unlink(), but not remove(), because we have remove() in <stdio.h>. I am using sigaction.s to test some features that we recently added to our PowerPC assembler. These are the "hi16[...]" and "lo16[...]" syntax, and also the extended names like "beq", "cmpwi", "li", "subi".
19 lines
449 B
C
19 lines
449 B
C
#include <signal.h>
|
|
|
|
/*
|
|
* Uses our bridge in sigaction.s when calling the signal handler.
|
|
* Mimics Linux __NR_signal by using SA_NODEFER | SA_RESETHAND.
|
|
*/
|
|
sighandler_t signal(int signum, sighandler_t handler) {
|
|
struct sigaction new, old;
|
|
int i;
|
|
|
|
new.sa_handler = handler;
|
|
new.sa_mask = 0; /* empty set */
|
|
new.sa_flags = SA_NODEFER | SA_RESETHAND;
|
|
|
|
i = sigaction(signum, &new, &old);
|
|
if (i < 0)
|
|
return SIG_ERR;
|
|
return old.sa_handler;
|
|
}
|