Newlib raise() - multiple definitions?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Newlib raise() - multiple definitions?

Post by JamesM »

I've ported newlib, and was having trouble working out exactly how I was supposed to find out what function a user had registered as a signal handler. As far as I could see, raise() (send signal to the current process) mapped immediately through to kill(getpid(), sig), and there were no macros to get signal functions etc (sigaction isn't implemented in newlib).

So anyway, I decided to write a small test program:

Code: Select all

void func(int sig)
{
  printf("Recieved signal: %d\n", sig);
}

... in main
signal(10, &func);
raise(10);
I ran it, and lo and behold it worked perfectly! Putting trace code into my kill() function (which was a stub) showed it wasn't being called at all - strange.

I then did a grep -r "_raise_r" ./libc/ in case I was missing something. I was. There is a *second* definition of raise(), in signal.c. This one calls a locally defined handler if one exists.

So, my question is - does anyone know why there are two definitions of the same function in two different files in the same directory: raise.c and signal.c ??

It seems strange.

Cheers,
JamesM
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

The one in signal.c is included in the build if the macro SIGNAL_PROVIDED is not defined. This provides a user-space emulation of raise() and signal() such that the only way to signal a process is to call raise() within that process (or its libraries) and is provided as an emulation for small embedded systems.

The one in raise.c is included if SIGNAL_PROVIDED is defined. This does not cause a signal() to be implemented (you must provide it) and it provides a stub raise, which calls the system call kill() which again you must provide.

Basically, either define SIGNAL_PROVIDED (and have configure detect it somehow) and provide kill() and signal() or just let newlib provide its own implementations. If you usethe newlib ones, though, you must ensure crt0 calls _init_signal. Need to add that to the wiki article at some point...

Regards,
John.

edit: You can add newlib_cflags="${newlib_cflags} -DSIGNAL_PROVIDED" to your host definition in newlib/configure.host if you're following OS Specific Toolchain. Editing the article is on my todo list when I get a chance.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Cheers for that. I hadn't seen the #ifdef SIGNALS_PROVIDED. Make sense.
Post Reply