Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

'c' unix signal problem 1

Status
Not open for further replies.

Gafling

Programmer
Nov 7, 2000
44
US
For the advanced 'c' programmer ... a signal problem ...

I am trying to use the unix alarm & signal functions to control an client
application. The code is essentially documented in the snippet below.
The intent of the program is to send a message and wait 10 seconds for a
reply. If the 'alarm(10)' expires, the program is to try to re-establish
the link before sending any more requests to the server.

However there is a problem. When server is offline or very slow in
responding and the 'alarm(10)' expires on the second time around, the
'sig_alarm' function is not invoked; the program appears to hang on the
read command. Re-stating the above: the program functions correctly when
the alarm(10) expires the first time but appears to hang when the
alarm(10) expires the second time.

Any guidance would be appreciated ...


Code example ...
Code:
/* Function to handle alarm signal */
void sig_alarm(int sig) {
    signal(SIGALRM, SIG_IGN);
    alarm_signal = 1;
    return;
}

/* Function read socket data */
int read_data(char *TEXT) {
        ...
    alarm_signal = 0;
    alarm(10);
    MesgCount = read(clisocket, &IN, ReadCount);
    alarm(0);
    if (alarm_signal == 1) return(8);
        ...
    return(0);
}

int startup(void) {
/* Allow for clean up if we get killed or we time out */
    signal(SIGALRM, sig_alarm);
        ...
        ...
/* Go read some data from the socket ... */
    i = read_data(&msg.mtext[0]);
    if ( i ) {
        switch (i) {
        case 1: ...
        case 2: ...
        case 8: ...
                signal(SIGALRM, sig_alarm);
                break;
        }
    }
        ...
        ...
}
 
1) alarm()
2) select()

alarm():
From the code I see, I believe the signal is disabled i.e: signal(SIGALRM, SIG_IGN); each time the signal handler is invoked. Just remove that line from the signal handler and it should work fine. (Note: on some Unices - on SVr? -, you have to re-enable the signal handler by re-issuing signal(SIGALRM, sig_alarm))

select():
When you intend to time-out on a file descriptor, a socket is a type of file descriptor, it is preferable to use select(). This call monitors the change in the state of the f.d. (such as 'data has arrived') and one of the option to the call is to specify a time-out. The select call will return if there is data to read or if the time-out expired. If it has timed-out, an error code will be returned (-1, errno=Esomething).

result = select(clisocket, ..., timeout...);
if (result == -1) return (8);
MesgCount = read(clisocket, &IN, ReadCount);
...
 
Why is the signal() function falling out of favour? What are its drawbacks?
 
Hello, Kulla.

The code I posted has several typo errors which may have confused 'Sebontheweb' leading to his comment #1 but his suggestions about the 'select' verb are correct. 'select' is a more complex but up-to-date way of timing file I-O activities primarily because it is more specific to I-O. The 'signal' way is subject to occasional failure because of several reasons, but I think it has to do most with the increasing complexity of *nix operating system in general.

Most 'man' pages suggest that 'signal' be replaced with 'sigaction'. Again, the newer way is more complex but it seems to be more reliable, probably because it is more focused. If you program in 'c' or 'c++' on *nix, 'select' and 'sigaction' should be added to your programming vocabulary. Examples are all over the web; just type 'sigaction' into Google and go for it.

gafling
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top