Pino
Pino

Reputation: 629

Catching SIGINT signal to terminate a custom shell

Hope you can help me to resolve this problem.

For school I have to transform Ctrl+C to a command which doesn't shut down the shell, but he reminds through printf() that I must type exit to close the shell. I don't even know where to start.

Thank a lot.

Upvotes: 1

Views: 2066

Answers (3)

Raman
Raman

Reputation: 2785

Ctrl+C sends an interrupt signal (SIGINT) to the running process.You can use signal() to catch SIGINT like this:

 #include<stdio.h>
 #include<signal.h>

 void sigint_handler(int sig)
 {
   printf("Type exit to close the shell!\n");
 }


  int main()
  {
    signal(SIGINT, sigint_handler);

    /*Your code should replace the while loop.*/
    while(1)
    {
        printf("Running!\n");
        getchar();
    }

    return 0 ;
  }

Upvotes: 0

TripeHound
TripeHound

Reputation: 2960

As you're talking about doing it from the shell, you probably want:

$ trap "echo Please type \'exit\' to close the shell." SIGINT
<Ctrl-C>
Please type 'exit' to close the shell.
$

This specifies a command to execute when the listed signal is trapped (the trap command can also trap other signals; SIGINT is the one generated by Ctrl-C). The \' protects the quote from being interpreted by the shell.

Upvotes: 0

P.P
P.P

Reputation: 121387

Here's a trivial implementation of handling SIGINT using sigaction which will work on posix systems. Left out error checking for brevity. The linked manual should explain about sigaction.

Basically the program loops through an infinite loop and break if user types exit. Using write as you can't use printf in signal handler. See signal manual for a list of functions that can be used safely in a signal handler.

#include<stdio.h>
#include<signal.h>
#include<string.h>
#include<stdlib.h>

char s[]="Type 'exit' to terminate\n";

void int_handler (int signum)
{
  write(fileno(stdin), s, sizeof s - 1);
}

int main (void)
{
  char str[256];
  struct sigaction sh;

  sh.sa_handler = int_handler;
  sigemptyset (&sh.sa_mask);
  sh.sa_flags = 0;
  sigaction (SIGINT, &sh, NULL);
  printf("%s", s);

  while(1) {
    fgets(str, sizeof str, stdin);
    char *p = strchr(str, '\n');
    if(p) *p = 0;
    if(!strcmp(str, "exit")) {
      printf("Exiting on request...");
      break;
    }
  }
  return 0;
}

Upvotes: 3

Related Questions