1. 程式人生 > >《深入理解計算機系統》之家庭作業8.25題答案

《深入理解計算機系統》之家庭作業8.25題答案

#include "csapp.h"


static sigjmp_buf env; //當呼叫sigsetjmp函式時將當前呼叫環境儲存在緩衝區env中,以供後面siglongjum使用


/*
** handler:一個訊號處理程式
*/
static void handler(int sig)
{
Alarm(0);  //如果有以前為程序登記的尚未超時的鬧鐘時鐘,而且本次呼叫的secs值是0,則取消以前的鬧鐘時鐘,其餘留值仍作為alarm函式的返回值。
siglongjmp(env, 1); //當控制到達這裡時執行跳轉,即重新跳回sigsetjmp處繼續執行,此時sigsetjmp返回非零
}




char *tfgets( char *s, int size, FILE *stream )
{
Signal( SIGALRM, handler ); //當核心向alarm函式的呼叫程序傳送一個訊號時,捕獲該訊號


Alarm(5);  //alarm函式在5秒內向呼叫程序傳送一個SIGALRM訊號


/*
** 如果使用者在5秒內執行了輸入,則alarm函式不會發送訊號,那麼訊號處理函式handler也就不會執行,
** 即不會發生非本地跳轉,於是sigsetjmp返回0,程式執行Fgets,tfgets函式返回指向輸入行的指標。
** 反之,如果使用者超過5秒沒有輸入,則alarm函式傳送訊號,呼叫程序捕獲該訊號並執行handler函式,
** 於是發生非本地跳轉,sigsetjmp返回非零,tfgets函式返回NULL。
** 
*/
if( sigsetjmp(env, 1) == 0 )  //設定一個可以被訊號處理程式使用的非本地跳轉,設定成功後sigsetjmp返回0
return ( Fgets(s, size, stream) );
else
return NULL;
}




int main()
{
char buf[MAXLINE];


while(1)
{
/*
** 關於bzero函式:
** 原型:extern void bzero(void *s, int n);
** 引數說明:s是要置零的資料的起始地址; n是要置零的資料位元組個數。
                ** 用法:#include <string.h>
                ** 功能:置位元組字串s的前n個位元組為零且包括‘\0’。
** 說明:bzero無返回值
*/
bzero(buf, MAXLINE); //將字元陣列buf全部清零


if( tfgets(buf, sizeof(buf), stdin) != NULL )
printf( "read:%s\n", buf );
else
printf( "timed out\n" ); //超時
}
exit(0);
}