0

I'm running a console using fgets() in a microcontroller. If I leave the console idle for too much time while fgets() is prompting for commands the watchdog timer would get triggered.

I wonder if it is possible to set a time limit on fgets() so that if the user doesn't provide commands after certain amount of time, fgets() expires?

  • 1
    No, not for `fgets`. You'll need to use some other approach. Such as `select` with a timeout followed by a `read`. In that case you'll need to also manage end of line detection yourself. – kaylum Mar 15 '20 at 03:34
  • You can theoretically get around blocking code with multi-threading, but not if you're talking about embedded systems. – C. Dunn Mar 15 '20 at 21:25

1 Answers1

0

Note

This answer might be completely useless if you are writing microcontroller code using something like HI-TECH C or Keil C51. In those cases, you will have to use some platform dependent solution.

There are a lot of things wrong with this example, but it shows how to interrupt fgets:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>

sigjmp_buf context;

volatile int alarm_occurred = 0;

void alarm_handler(int signum) {
    alarm_occurred = 1;
    siglongjmp(context, -1);
}

int main() {
    char buffer[80];

    signal(SIGALRM, alarm_handler);

    while (1) {
        char *result;
        if (sigsetjmp(context, 1) == 0) {
            // The call to sigsetjump will cause flow to go here
            alarm(3);
            printf("Enter a string: ");
            result = fgets(buffer, sizeof(buffer), stdin);
        }
        else {
            // The call to siglongjump will cause flow to go here
            printf("\n");
            continue;
        }
    }

    return 0;
}

Output

Enter a string: 
Enter a string: 
...
Enter a string: 

I've never used sigsetjmp or siglongjmp before, and I know better than to do anything other than set a flag in a signal handler, but hopefully the people who do know how to use these properly can edit the answer to fix the problems.