For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > January 2006 > Question regarding signals









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Question regarding signals
Chad

2006-01-18, 10:00 pm

In the book "Advanced Programming in the Unix Environment", 2nd
edition, on page 290, the books has the following:

"Signals occur at what appear to be random times to the process. The
process can't simply test a variable (such as errno) to see whether a
signal has occurred; instead, the process has to tell the kernel "if
and when this signals occurs, do the following.""

However, on page 304, they have the following code snippet:

if ((n=read(fd, buff, BUFFSIZE)) < 0) {
if(errno == EINTR)
goto again: /*just an interrupted system call*/
/*handle other errors*/
}

If the process can't test a variable such as errno, then now come it
gets tested when the signal gets sent to a system call?

Thanks in advance
Chad

Barry Margolin

2006-01-18, 10:00 pm

In article <1137636900.245080.285560@g47g2000cwa.googlegroups.com>,
"Chad" <cdalten@gmail.com> wrote:

> In the book "Advanced Programming in the Unix Environment", 2nd
> edition, on page 290, the books has the following:
>
> "Signals occur at what appear to be random times to the process. The
> process can't simply test a variable (such as errno) to see whether a
> signal has occurred; instead, the process has to tell the kernel "if
> and when this signals occurs, do the following.""
>
> However, on page 304, they have the following code snippet:
>
> if ((n=read(fd, buff, BUFFSIZE)) < 0) {
> if(errno == EINTR)
> goto again: /*just an interrupted system call*/
> /*handle other errors*/
> }
>
> If the process can't test a variable such as errno, then now come it
> gets tested when the signal gets sent to a system call?


This is a special case.

When a signal arrives while you're in the read() system call, normal
handling of the signal occurs, and then read() returns immediately
rather than continuing to wait for input (in some cases you can tell the
OS that it should resume the system call, but not all of them). This
errno setting is not a way of detecting that a signal occurred, but just
a way of knowing why read() returned without any data.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Pascal Bourguignon

2006-01-18, 10:00 pm

"Chad" <cdalten@gmail.com> writes:

> In the book "Advanced Programming in the Unix Environment", 2nd
> edition, on page 290, the books has the following:
>
> "Signals occur at what appear to be random times to the process. The
> process can't simply test a variable (such as errno) to see whether a
> signal has occurred; instead, the process has to tell the kernel "if
> and when this signals occurs, do the following.""
>
> However, on page 304, they have the following code snippet:
>
> if ((n=read(fd, buff, BUFFSIZE)) < 0) {
> if(errno == EINTR)
> goto again: /*just an interrupted system call*/
> /*handle other errors*/
> }
>
> If the process can't test a variable such as errno, then now come it
> gets tested when the signal gets sent to a system call?


This is different. Here, errno reports the fact that a signal arrived
while the process was inside the read system call, before any byte was
read.


But with a simple signal handler (and most of the time, that's all you
should do in the signal handler anyways), you can still just test a
variable. Well, if you want to test several signals, you can use a
sigset instead of a simple scalar variable:

% cat testsig.c
#include <stdio.h>
#include <signal.h>

sigset_t signal_received;

void do_something() {sleep(10);}
void do_something_and_report_signals(){
while(1){
int signum;
no_more_signals:
do_something();
for(signum=1;signum<SIGRTMAX;signum++){
if(1==sigismember(&signal_received,signum)){
printf("Got signal %d\n",signum);
fflush(stdout);
if(signum==SIGINT){ exit(0); }
sigdelset(&signal_received,signum);}}}}

void handler(int signal){ sigaddset(&signal_received,signal); }

int main(){
int signum;
sigemptyset(&signal_received);
for(signum=1;signum<SIGRTMAX;signum++){
printf("signal(%d)=%d\n",signum,signal(signum,handler));}
fflush(stdout);
do_something_and_report_signals();
return(0);}

% gcc -o testsig testsig.c
% ./testsig & pid=$!
% for s in $(seq 20 30) ; do kill -$s $pid ; sleep 1; done ; kill -2 $pid
[2] 7826
signal(1)=0
signal(2)=0
signal(3)=0
signal(4)=0
signal(5)=0
signal(6)=0
signal(7)=0
signal(8)=0
signal(9)=-1
signal(10)=0
....
signal(57)=0
signal(58)=0
signal(59)=0
signal(60)=0
signal(61)=0
signal(62)=0
signal(63)=0
Got signal 20
Got signal 21
Got signal 22
Got signal 23
Got signal 24
Got signal 25
Got signal 26
Got signal 27
Got signal 28
Got signal 29
Got signal 30
Got signal 2
[2]+ Done ./testsig
%

--
__Pascal Bourguignon__ http://www.informatimago.com/

"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2010 codecomments.com