Я создаю библиотеку сообщений, которая берет фильтр и использует его для чтения и записи. Протокол определяет тайм-ауты, поэтому я хочу их использовать.FILE * чтение с таймаутом
Я использую fread(3)
и fwrite(3)
. Я слышал о select(2)
, и это то, что я ищу, за исключением того, что он использует файловые дескрипторы, а не libc filestreams. Я хочу поддерживать настраиваемые потоки потоков, созданные с помощью fopencookie(3)
, полезные для тестов и прочего. Я попытался создать SIGALRM
с alarm(2)
, чтобы получить ошибку EINTR
из fread(3)
(настройки обратного вызова для SIGALRM
с помощью signal(2)
), но это не остановит fopen
вызова, как ожидалось ...
Спасибо заранее для любого решения ,
EDIT: Таким образом, похоже, что это работает .. но только один раз. На втором вызове, он не ... Оо
/**
* 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() для объекта общей памяти undefined. " – user3629249
Итак, я попробовал' select' и 'fileno'. Но факт: 'fileno' возвращает -1 в пользовательский поток, созданный с помощью' fopencookie', поэтому я не могу использовать 'select' с ним. И если я хочу проверить тайм-ауты с пользовательскими фильтрами ... так что это не сработает для меня. :/ – Cakeisalie5