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