By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,110 Members | 1,543 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,110 IT Pros & Developers. It's quick & easy.

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

P: 5
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(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):
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 !!!
Feb 3 '09 #1
Share this Question
Share on Google+
2 Replies


Expert 100+
P: 1,510
The code would not compile initially so I fixed a couple of problems, indicated by // ** comments
Expand|Select|Wrap|Line Numbers
  1. include <stdio.h>
  2. #include <signal.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6.  
  7. #define BUFFER_SIZE 50   //  ** added
  8. #define MAX_LINE 100
  9.  
  10. static char buffer[BUFFER_SIZE];
  11.  
  12. void handle_SIGINT(int sig_num ){
  13. write(STDOUT_FILENO, buffer, strlen(buffer));
  14. exit(0);
  15. }
  16.  
  17. int main(){
  18.  
  19.  
  20. struct sigaction handler;
  21. handler.sa_handler = handle_SIGINT; //* <=== ERROR */
  22. handler.sa_flags = 0;
  23. sigemptyset(&handler.sa_mask);
  24. sigaction(SIGINT, &handler, NULL);
  25. strcpy(buffer, "Caught <Ctrl> <c>\n");
  26.  
  27.  
  28. char inputBuffer[MAX_LINE]; /*buffer to hold the command entired */
  29. char* args[MAX_LINE/ +1]; /*command line ( of 80 ) has max of 40 argument */
  30. int background; /*equals 1 if a command is folowed by '&' */
  31. //setup(inputBuffer, args , &background); /*setup the command line */
  32.  
  33. pid_t pid;
  34. pid = fork();
  35.  
  36. switch(pid){                 //  *** changed : to {
  37. case -1:
  38. //fork() error.
  39.  
  40. case 0:
  41. // call execvp(args[0], args) to run shell commands
  42. default:;
  43. }                // ** added }
  44. //.................
  45. printf("Done");
  46. while(1);        // added
  47. return(0);        // added
  48. }
  49.  
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
Expand|Select|Wrap|Line Numbers
  1. $sig
  2. Caught <Ctrl> <c>
  3. DoneCaught <Ctrl> <c>
  4. Done
  5. $
  6.  
Feb 6 '09 #2

P: 5
Oh, many thanks to you. Wish a best health 4 you :)
Feb 6 '09 #3

Post your reply

Sign in to post your reply or Sign up for a free account.