*BSD News Article 53350


Return to BSD News archive

#! rnews 2643 bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!simtel!zombie.ncsc.mil!news.mathworks.com!newsfeed.internetmci.com!howland.reston.ans.net!blackbush.xlink.net!snert!ka.sub.net!rz.uni-karlsruhe.de!news.uni-stuttgart.de!uni-regensburg.de!lrz-muenchen.de!informatik.tu-muenchen.de!gruner
From: gruner@Informatik.TU-Muenchen.DE (Armin Gruner)
Newsgroups: comp.unix.bsd.misc
Subject: Re: READ(2) timeout after minutes?
Date: 17 Oct 1995 23:04:23 GMT
Organization: Technische Universitaet Muenchen, Germany	
Lines: 67
Distribution: world
Message-ID: <461cpn$ddb@sunsystem5.informatik.tu-muenchen.de>
References: <460c28$776@bdanwb.knmi.nl>
NNTP-Posting-Host: hprbg5.informatik.tu-muenchen.de
X-Newsreader: NN version 6.5.0 #5 (NOV)

rtholtma@knmi.nl (Johan Holtman) writes:

>Hi,
>Suppose the read(2) system call takes a very long time (eg, because of
>a file being archived). HOW can I MAKE read(2) timeout after X minutes?
>Q1. How can I set a timeout on read for eg. 5 minutes?
>I tried to do this with alarm() and signal(). This signal is send
>DURING the read, but only processed AFTER the read system call.
>Q2. How come? Other signals are directly handled?
>If you are that experienced to give the answer, please also send
>an email to rtholtma@knmi.nl.
>Thanks a lot,
>		Johan Holtman

Certain system calls on BSD derived systems are restarted after
an interrupt by default.

Under SunOS 4.x (and most 4.2/4.3BSD based systems), you would write:

siginterrupt(SIGALRM, 1);

to make signal ALARM interrupting system calls like read(), write() 
on slow devices.

Then you would add a handler (which does probably nothing),

void catcher(sig) int sig; {}

...
sa.sa_handler = catcher;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM, sa);
siginterrupt(SIGALRM, 1);
...

alarm(5 * 60);	/* interrupt read after 5 minutes */
n = read(fd, buf, len);
alarm(0);

if (n < 0 && errno == EINTR)
  /* TIMEOUT */

...

Under HP-UX (probably under SVR3/4 based systems, too),
system calls are interrupted _per default_.
If you want to have them restarting, you would write your signal handler like:

void catcher(sig, code, scp)
int sig, code;
struct sigcontext *scp;
{
  if (scp && scp->sc_syscall != SYS_NOTSYSCALL)
    scp->sc_syscall_action = SIG_RESTART;
}

Please note that this is HP-UX specific an non portable most probably..

Under Solaris 2.x and OSF/1 , you can change the behaviour with the flag
SA_RESTART in sa_flags giving to sigaction().

Other platform do vary. you should carefully read the man pages, like
sigaction(2), signal(2), signal(5) and sigvec(2).

Regards & Greetings from Munich,
	Armin