Page 1 of 1

Stupid behaviour in newlib?

Posted: Sun Nov 18, 2007 8:59 am
by JamesM
After spending ages wondering why my signals weren't being delivered I peered into the newlib source code for raise():

Code: Select all

  func = ptr->_sig_func[sig];
  if (func == SIG_DFL)
    return _kill_r (ptr, _getpid_r (ptr), sig);
  else if (func == SIG_IGN)
    return 0;
  else if (func == SIG_ERR)
    {
      ptr->_errno = EINVAL;
      return 1;
    }
  else
    {
      [b]ptr->_sig_func[sig] = SIG_DFL;[/b]
      func (sig);
      return 0;
    }
I've highlighted the interesting part in bold: It removes the signal handler whenever raise() is called! WHAT?!?! why? I've implemented an ugly hack involving calling signal() three times whenever I send a signal to save and reinstall the correct signal handler but I shouldn't have to do this - this behaviour is not in the POSIX spec - what's it all about?

Any ideas?

Posted: Sun Nov 18, 2007 11:51 pm
by pcmattman
Edit the source, remove that line, and recompile :D

Try the Newlib mailing list, they may have a good reason for it.

Posted: Mon Nov 19, 2007 1:21 am
by jnc100
This is a 'feature' only in the newlib emulation of signals for embedded targets (i.e. in signal.c). If you provide your own implementations of kill and signal, then it shouldn't be a problem (this is also required for sending signals between processes). They note it at the top of the file too:
signal.c wrote:the default handling for the signal is restored (SIG_DFL), and the function func is called with sig as its argument
Still, I've absolutely no idea why they do it though. Perhaps it seemed more logical to have this particular functionality on the device the original author was developing for. I have to agree with pcmattman, the mailing list is probably the way to go.

Regards,
John.