How to handle Control-C signal while designing a shell? How to handle Control-C signal while designing a shell? shell shell

How to handle Control-C signal while designing a shell?


Jonathan Leffler provided helpful hints (though not sufficient, at least on some popular operating system):

  • Look at what scanf() returns.
  • Don't use loop() in the signal handler
  • Don't use signal() — use sigaction(). In your case, this has two advantages:
    • Restoring the signal action to the default state on call of the signal handler can be avoided, so you don't have to change the action again in the handler.
    • Restarting the read() system call (inside scanf()) can be avoided, so that scanf() returns and you can react to the interrupt in the first place.

So, the signal handler can be just

void sigintHandler(int sig_num){    printf("\n");   // or perhaps better write(1, "\n", 1)}

The signal(SIGINT, sigintHandler); in main() can be replaced with

  sigaction(SIGINT, &(struct sigaction){ .sa_handler = sigintHandler }, NULL);

and the scanf("%s",a); with

      if (scanf("%s", a) == EOF)      {          if (errno == EINTR) continue; // read operation interrupted by signal          return;      }

EOF is returned on interrupt as well as on end of file, so the cases are to be distinguished through errno. Besides, it's nice if your program provides a way to exit it, thus the return.