我正在制作一个通信库,该通信库接受一个文件流,并使用它来读写。该协议定义了超时,因此我想使用它们。
我正在使用fread(3)
和fwrite(3)
。我听说过select(2)
,这是我正在寻找的东西,除了它使用文件描述符而不是libc文件流-我想支持使用fopencookie(3)
创建的自定义文件流,这对于测试和其他事情也很有用。我尝试使用SIGALRM
设置alarm(2)
来从EINTR
中获取fread(3)
错误(使用SIGALRM
为signal(2)
设置回调),但是它不会停止fopen
调用,因为预期...
在此先感谢您提供任何解决方案。
编辑:所以看起来像这样。.但是只有一次。在第二次通话中,没有...哦
/**
* 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);
}
再次感谢您的帮助^^
最佳答案
函数:fdopen()
将使您从文件描述符获得文件指针。
然后,您可以使用函数:select()
和从fdopen()
返回的文件指针。