2016-10-08 94 views
0

我正在製作一個採用文件流並使用它讀取和寫入的通信庫。該協議定義超時,所以我想使用它們。我使用fread(3)fwrite(3)。我聽說過select(2),這是我正在尋找的,除了它使用文件描述符而不是libc文件流 - 我想支持使用fopencookie(3)創建的自定義文件流,對於測試和其他事情也很有用。我曾嘗試建立SIGALRMalarm(2)fread(3)得到EINTR錯誤(使用signal(2)建立回調SIGALRM),但預期不會停止fopen電話...FILE *超時讀取

預先感謝任何解決方案。

編輯:所以它看起來像這樣工作..但只有一次。在第二個電話,它不......哦哦

/** 
* sigalrm_handler: 
* Shut up SIGALRM. 
* 
* @arg code  signal code (always SIGALRM) 
*/ 

static __thread jmp_buf env_alrm; 
static void sigalrm_handler(int signo) 
{ 
    (void)signo; 
    /* restore env */ 
    longjmp(env_alrm, 5); 
} 

/** 
* _p7_fread: 
* Read file with timeout. 
* 
* @arg ptr   the buffer pointer 
* @arg size  the size of an item 
* @arg nitems  the number of items in the buffer 
* @arg stream  the stream 
* @arg timeout  the timeout (seconds) 
* @return    the number of read bytes 
*/ 

size_t _p7_fread(void *ptr, size_t size, size_t nitems, FILE *stream, 
    int timeout) 
{ 
    size_t read_count = 0; 

    /* set long jump */ 
    int val = setjmp(env_alrm); 
    if (!val) { 
    /* setup signal handler */ 
     if (signal(SIGALRM, &sigalrm_handler) == SIG_ERR) 
      return (0); 

     /* setup alarm */ 
     alarm(timeout); 

     /* read */ 
     read_count = fread(ptr, size, nitems, stream); 
    } else 
     errno = EINTR; 

    /* unset signal handler and alarm */ 
    signal(SIGALRM, NULL); 
    alarm(0); 

    /* return */ 
    return (read_count); 
} 

再次,感謝所有幫助^^

回答

0

功能:fdopen()將讓你從文件描述符文件指針。

然後,您可以使用函數:select()以及從fdopen()返回的文件指針。

+0

但是FILE *結構的內部緩衝區怎麼樣?那麼沒有文件描述符的文件流(我正在考慮使用'fopencookie'創建的文件流)呢? – Cakeisalie5

+0

這是來自:<>「fdopen()函數將一個流與現有的文件描述符fd相關聯。流的模式(值」r「,」r +「,」w「,」w +「, 「a」,「a +」)必須與文件描述符的模式兼容,新流的文件位置指示符被設置爲屬於fd的文件位置指示符,並且錯誤和文件結束指示符被清除模式「 w「或」w +「不會導致文件被截斷,文件描述符不會被重複使用,並且在fdopen()創建的流關閉時將被關閉。將fdopen()應用到共享內存對象沒有定義。「 – user3629249

+0

所以我嘗試了'select'和'fileno'。但事實上'fileno'在用'fopencookie'創建的自定義流上返回-1,所以我不能使用'select'。如果我想用自定義文件流測試超時...所以這對我不起作用。 :/ – Cakeisalie5