sigjmp_buf timeoutbuf;
sigjmp_buf toplevel;
static void timer(int sig)
{
int save_errno = errno;
(void)sig; /* Shut up unused warning */
alarm(0);
timeout += rexmtval;
trace("Transfer Time Out, Re-Trying..");
if (timeout >= maxtimeout)
{
trace("Re-Try Counter Exceeded The Limit, Abort.\n");
errno = save_errno;
siglongjmp(toplevel, 1); ;//如果超过定时次数,则跳到toplevel
}
errno = save_errno;
siglongjmp(timeoutbuf, 1);//如果没有超过定时次数,则跳到timeoutbuf
}
//第一次调用的时候返回0, 第一次执行时函数返回0, 当调用过siglongjmp后,会从这里重新执行,但是函数 的返回值变成了1
///如果超过定时次数, 则跳转到此
if(sigsetjmp(toplevel, 1) == 0) /* check we are the first time here */
rv = tftp_recvfile(fd, src, m_mode);
(void)sigsetjmp(timeoutbuf, 1); 如果没超过定时次数,则跳转到此处继续执行,
bsd_signal(SIGALRM, timer);
alarm(rexmtval);
do
{
fromlen = sizeof(from);
n = recvfrom(f, dp, PKTSIZE, 0, (struct sockaddr*) &from, &fromlen);
}
while (n <= 0);
alarm(0);
上面的接收函数一旦超时,将会进入timer执行。
sigsetjmp 第二个参数一定要 >0 如1 不然会有问题。。用0调试了好久.。。才发现人家的例子上都用的1。。