[uClibc]mips signals working somewhat...

Phil Hopely phil at ayrnetworks.com
Wed Sep 4 17:54:35 UTC 2002


Hello uclibc,


Continuing the mini-saga of mips signal handling, I found that the 
appended wrapping hack to the definition of the "execve" syscall within:

uclibc/libc/sysdeps/linux/common/syscalls.c

... allows for somewhat more sane signal handling behaviour to occur - 
though I am quite sure that this is not hygenically compliant :)

I qualify working with "somewhat" due to the fact that the initial 
"bash" that starts after login (spawned from tinylogin) does not respond 
to SIGINT (control+c or kill -2) -- though subsequent shells & processes 
do appear to respond to this (and other) signal(s) as far as we've 
tested (though we may have noted a case where a SIGCHLD may not be 
delivered to a parent, but I need to investigate this further to ensure 
something else is not in fact the cause).

I would love to hear any suggestions on more appropriate locations or 
procedures for signal handling initialization!

So without further ado here is the hack:

//#define __NR_execve           11
#ifdef L_execve
#include <unistd.h>
/*
_syscall3(int, execve, const char *, filename, char *const *, argv,
          char *const *, envp);
*/


#include <signal.h>


static int execve_real (const char *filename, char *const *argv, \
          char *const *envp) \
{ \
long __res, __err; \
__asm__ volatile ("move\t$4,%3\n\t" \
                  "move\t$5,%4\n\t" \
                  "move\t$6,%5\n\t" \
          "li\t$2,%2\n\t" \
          "syscall\n\t" \
          "move\t%0, $2\n\t" \
          "move\t%1, $7" \
                  : "=r" (__res), "=r" (__err) \
                  : "i" (__NR_execve),"r" ((long)(filename)), \
                                      "r" ((long)(argv)), \
                                      "r" ((long)(envp)) \
                  : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \
            "$13","$14","$15","$24"); \
if (__err == 0) \
    return (int) __res; \
errno = __res; \
return -1; \
}


int execve (const char *filename, char *const *argv, char *const *envp)
{
sigset_t set1;
int i;

/* initialize all signal handlers */

for(i=1;i<_NSIG;i++)
    signal(i,SIG_DFL);

sigfillset(&set1);

if (sigprocmask(SIG_UNBLOCK,&set1,NULL)<0)
    printf("%s: failed sigprocmask\n",__FUNCTION__);

return(execve_real(filename, argv, envp));
}


Cheers!
Phil





More information about the uClibc mailing list