Catch < Ctrl + C > on Linux ==> can not run execvp

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • thanhnh
    New Member
    • Jan 2009
    • 5

    #1

    Catch < Ctrl + C > on Linux ==> can not run execvp

    Hi. I have to write a simple Shell with History feature. First, I get a string from command line. The command line is split into tokens. And then, I call fork ( ) to create a new process. The child process will call execvp(args[0], args) in order to execute the string command line. When user press < Ctrl + C > ( signal SIGINT ) , I have to read a file and print out 10 last commands.

    My problem is: when I embed small code to catch < Ctrl + C > into my program as bold text below, I can not run execvp( ). The error is : bad address !!!

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

    #define BUFFER_SIZE 50

    static char buffer[BUFFER_SIZE];

    void handle_SIGINT(i nt sig_num ){
    write(STDOUT_FI LENO, buffer, strlen(buffer)) ;
    exit(0);
    }


    int main(){

    /*
    struct sigaction handler;
    handler.sa_hand ler = handle_SIGINT; //* <=== ERROR */
    handler.sa_flag s = 0;
    sigemptyset(&ha ndler.sa_mask);
    sigaction(SIGIN T, &handler, NULL);
    strcpy(buffer, "Caught <Ctrl> <c>\n");


    */
    char inputBuffer[MAX_LINE]; /*buffer to hold the command entired */
    char* args[MAX_LINE/ +1]; /*command line ( of 80 ) has max of 40 argument */
    int background; /*equals 1 if a command is folowed by '&' */
    setup(inputBuff er, args , &background) ; /*setup the command line */

    pid_t pid;
    pid = fork();

    switch(pid):
    case -1:
    //fork() error.

    case 0:
    // call execvp(args[0], args) to run shell commands
    default:
    //............... ..
    return(0);
    }

    How can I fix this prolem ? Help me, please !!!
  • horace1
    Recognized Expert Top Contributor
    • Nov 2006
    • 1510

    #2
    The code would not compile initially so I fixed a couple of problems, indicated by // ** comments
    Code:
    include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define BUFFER_SIZE 50   //  ** added
    #define MAX_LINE 100
    
    static char buffer[BUFFER_SIZE];
    
    void handle_SIGINT(int sig_num ){
    write(STDOUT_FILENO, buffer, strlen(buffer));
    exit(0);
    }
    
    int main(){
    
    
    struct sigaction handler;
    handler.sa_handler = handle_SIGINT; //* <=== ERROR */
    handler.sa_flags = 0;
    sigemptyset(&handler.sa_mask);
    sigaction(SIGINT, &handler, NULL);
    strcpy(buffer, "Caught <Ctrl> <c>\n");
    
    
    char inputBuffer[MAX_LINE]; /*buffer to hold the command entired */
    char* args[MAX_LINE/ +1]; /*command line ( of 80 ) has max of 40 argument */
    int background; /*equals 1 if a command is folowed by '&' */
    //setup(inputBuffer, args , &background); /*setup the command line */
    
    pid_t pid;
    pid = fork();
    
    switch(pid){                 //  *** changed : to {
    case -1:
    //fork() error.
    
    case 0:
    // call execvp(args[0], args) to run shell commands
    default:;
    }                // ** added }
    //.................
    printf("Done");
    while(1);		// added
    return(0);		// added
    }
    it compiles and when run forks() a child proceess and the parent and child loop at the while(1); statement.
    when I hit <CTRL/C> it is caught and both processes print "Caught <Ctrl> <c>" then "Done" then stop. e.g. a run gave
    Code:
    $sig
    Caught <Ctrl> <c>
    DoneCaught <Ctrl> <c>
    Done
    $

    Comment

    • thanhnh
      New Member
      • Jan 2009
      • 5

      #3
      Oh, many thanks to you. Wish a best health 4 you :)

      Comment

      Working...