3

I am building a background service for a embedded linux device in C. Every hour a file is read either from a network share or a usb device, but if the network or usb device was plugged out, fopen never returns and the service freezes. I am not allowed to use async methods like pthread or fork to read that file, so i am looking for a solution with a timeout or something non-blocking to test if the file (or device) is available.

The code examples below are freezing on fopen/fdopen.

FILE* f = fopen("/path/to/file", "r"); //freezes if device not available;
if(f)
{
    < .. read file .. >
    fclose(f);
}

////////////////////////////////////////////

FILE* f = NULL;
int fd  = open("/path/to/file", O_RDONLY|O_NONBLOCK);
if(fd>=0)
{
    f= fdopen(fd, "r");//freezes if device not available
}

if(f)
{
    < .. read file .. >
    fclose(f);
}
else
{
    if(fd>=0){close(fd);}
}

edit: the answers for fopen does not return do not solve my issue. i do know why this is happening, but the service must not wait for a unresponsive device. as described above, i need a non blocking solution or a timeout.

  • Possible duplicate of [fopen does not return](https://stackoverflow.com/questions/4490343/fopen-does-not-return) – Stargateur Jul 03 '17 at 23:50
  • Use an empty-body signal handler, and a timeout signal, so that the `open()`/`fopen()`/`fdopen()` fails with `errno==EINTR` after sufficient time has passed. I have an CC0/Public Domain example [in this answer](https://stackoverflow.com/a/12765121/1475978) if you want multiple concurrent timeouts using only one signal. – Nominal Animal Jul 03 '17 at 23:51
  • 1
    It sounds like maybe your process is getting stuck in an uninterruptible sleep (a.k.a. disk wait). If this is the case, `ps` will show a status of `D`. The situation can't be corrected with a signal - even `SIGKILL` won't kill a process in this state. You can't fix the problem in userspace. You can't even work around it given the constraint of a single thread. You must instead find a way to convince the relevant driver (which might be a filesystem driver or a USB device driver) to give up the operation instead of retrying forever For example, with NFS there are mount options you can tweak. –  Jul 04 '17 at 01:01
  • I tried to interrupt fopen with a signal like @Nominal Animal mentioned, but no luck. currently a cronjob is used to test if the service is unresponsive, but thats no long term solution either. – Captain Obvious Jul 04 '17 at 01:23

0 Answers0