2016-10-08 97 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