segmentation fault. ubuntu version dependent -
#include <string.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <signal.h> #define max_cmd_arg 10 #define max_cmd_grp 10 const char *prompt = "myshell> "; char* cmdgrps[max_cmd_grp]; char* cmdvector[max_cmd_arg]; char cmdline[bufsiz]; enum stat{ none, fg, bg, }; int status=none; int pid=0; void sigint_handler(int sign){ fputs("\n",stdout); } void fatal(char *str) { perror(str); exit(1); } int makelist(char *s, const char *delimiters, char** list, int max_list) { if((s == null) || (delimiters == null)) return -1; char *snew = s + strspn(s, delimiters); /* delimitersė„¼ skip */ if((list[0] = strtok(snew, delimiters)) == null) return 0; int numtokens = 1; while(1) { if((list[numtokens] = strtok(null, delimiters)) == null) break; if(numtokens == (max_list - 1)) return -1; numtokens++; } return numtokens; } void execute_cmdgrp(char *cmdgrp) { int count = makelist(cmdgrp, " \t", cmdvector, max_cmd_arg); int size = strlen(cmdvector[count-1]); if(size > 0 && cmdvector[count-1][size-1] == '&') { status=bg; cmdvector[count-1][size-1] = '\0'; if(strlen(cmdvector[count-1]) == 0) cmdvector[count-1] = null; }else{ status=fg; } //printf(cmdvector[0]); switch(pid=fork()) { case -1: fatal("fork error"); break; case 0: // child process execvp(cmdvector[0], cmdvector); fatal("exec error"); break; default: break; } } void do_if_exit_cmd(const char* cmdgrp) { char* s = strdup(cmdgrp); makelist(s, " \t", cmdvector, max_cmd_arg); if(strncasecmp(cmdvector[0], "exit", 4) == 0) { free(s); exit(0); } free(s); } int do_if_cd_cmd(const char* cmdgrp) { char* s = strdup(cmdgrp); makelist(s, " \t", cmdvector, max_cmd_arg); if(strncmp(cmdvector[0], "cd", 2) == 0) { chdir(cmdvector[1]); free(s); return 1; } free(s); return 0; } void execute_cmdline(char* cmdline) { int count = makelist(cmdline, ";", cmdgrps, max_cmd_grp); if(count==0) pid=0; for(int = 0; < count; ++i) { do_if_exit_cmd(cmdgrps[i]); if(do_if_cd_cmd(cmdgrps[i])) continue; execute_cmdgrp(cmdgrps[i]); } } int main(int argc, char**argv) { struct sigaction act; act.sa_handler = sigint_handler; sigaction(sigint, &act, null); sigaction(sigquit, &act, null); while(1) { fputs(prompt, stdout); cmdline[0]=0; fgets(cmdline, bufsiz, stdin); cmdline[strlen(cmdline) - 1] = '\0'; execute_cmdline(cmdline); if(status==fg && pid){ int wid; int status; while((wid=wait(&status))!=pid && wid!=-1); } } }
above code simple concept shell shell ignore sigint(^c) , sigquit(^) compile g++ {filename}
the problem is working in ubuntu 14.04 64bit , 12.04 64bit in ubuntu 12.04 32 bit when press ^c, raises segmentation fault...
if change &status => null in line 'while((wid=wait(&status))!=pid && wid!=-1);' works without error
what's wrong in code? why dose error appear in ubuntu version while others not ..
there things not permitted in signal handlers, 1 of them call functions not async-signal-safe.
one of under posix systems in fputs()
little snippet:
void sigint_handler(int sign){ fputs("\n",stdout); }
is not idea.
i tend use signal handlers setting variables can picked , actioned main thread of control, things like:
int finished = 0; void sigint_handler(int sign){ finished = 1; }
where main program has loop like:
while (!finished) dosomework();
Comments
Post a Comment