Настройте таймер с помощью обработчика сигнала и дождитесь открытия вызова на fifo.Если открытие завершается неудачно с помощью errno=EINTR
и ваш обработчик запустился, вызов open
был прерван вашим таймером, т. Е. Истекло время ожидания.
Пример кода:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
volatile sig_atomic_t abort_eh;
void handler(int Sig)
{
abort_eh = 1;
}
int main()
{
struct sigaction sa;
sa.sa_flags = 0;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM,&sa,0);
//try to ensure the fifo exists
(void)mkfifo("fifo",0600);
//open with a timeout of 1s
alarm(1);
int fd;
do{
if (0>(fd=open("fifo",O_RDONLY)))
if(errno==EINTR){
if(abort_eh) return puts("timed out"),1;
else continue; //another signal interrupted it, so retry
}else return perror("open"),1;
}while(0);
alarm(0); //cancel timer
printf("sucessfully opened at fd=%d\n", fd);
}
setitimer
или timer_create
/ timer_settime
обеспечивают более точные таймеры лучше, чем alarm
.Они также имеют возможность установки таймера для повторения, что позволяет вам выполнять повторную сигнализацию в случае, если первый сигнал «пропущен» (т. Е. Был запущен незадолго до того, как был введен вызов open
, и, таким образом, не смог прервать потенциально бесконечный блокирующий системный вызов).