0
我正在制作一个采用文件流并使用它读取和写入的通信库。该协议定义超时,所以我想使用它们。我使用fread(3)
和fwrite(3)
。我听说过select(2)
,这是我正在寻找的,除了它使用文件描述符而不是libc文件流 - 我想支持使用fopencookie(3)
创建的自定义文件流,对于测试和其他事情也很有用。我曾尝试建立SIGALRM
与alarm(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);
}
再次,感谢所有帮助^^
但是FILE *结构的内部缓冲区怎么样?那么没有文件描述符的文件流(我正在考虑使用'fopencookie'创建的文件流)呢? – Cakeisalie5
这是来自:<>“fdopen()函数将一个流与现有的文件描述符fd相关联。流的模式(值”r“,”r +“,”w“,”w +“, “a”,“a +”)必须与文件描述符的模式兼容,新流的文件位置指示符被设置为属于fd的文件位置指示符,并且错误和文件结束指示符被清除模式“ w“或”w +“不会导致文件被截断,文件描述符不会被重复使用,并且在fdopen()创建的流关闭时将被关闭。将fdopen()应用到共享内存对象没有定义。“ – user3629249
所以我尝试了'select'和'fileno'。但事实上'fileno'在用'fopencookie'创建的自定义流上返回-1,所以我不能使用'select'。如果我想用自定义文件流测试超时...所以这对我不起作用。 :/ – Cakeisalie5