linux - Can't solve Segmentation fault (core dumped) in c -
we writing program has mimic linux shell. consisted of parts. every part previous part did, plus extra.
- part 1 runs single commands ls, pwd etc. no parameters no redirection.
- part 2 runs single commands plus redirection.
this stuck.. compile myshell 2 without errors. when typing command segmentation fault. we're sorry writing out code here(myshell 1 not included), wanted make sure have need tell wrong.
functions.h
#ifndef functions_h #define functions_h #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #define max 260 extern int argcounter(char *argline,char *delim); extern void myexec(char *argline,int howmany,char *delim); extern char **argarray(char* argline,int howmany,char *args[],char *delim); void myexecredir(char **tokens,char* argline, int howmany); #endif
functions.c
#include "functions.h" int argcounter(char *argline,char *delim) { char *temp; memcpy(temp,argline,strlen(argline)); char *pointer = strtok(temp, delim); int counter = 0; while (pointer != null) { counter++; pointer = strtok(null, delim); } return counter; } void myexec(char *argline,int howmany,char *delim) { char temp[max]; memset(temp,0,max); char *args[howmany]; argline[strlen(argline)-1] = '\0'; //argarray breaks argline , returns array contains each argument argarray(argline,howmany,args,delim); execvp(args[0],args); perror("error: wrong command!"); } char **argarray(char *argline,int howmany,char *args[],char *delim) { args[howmany] = null; char *pointer = strtok(argline, delim); int counter = 0; while (pointer != null) { args[counter]=pointer; counter++; pointer = strtok(null, delim); } return args; } void myexecredir(char **tokens,char* argline, int howmany) { char *delim3="<"; char *delim4=">"; int howmanyin= argcounter(argline,delim3); int howmanyout= argcounter(argline,delim4); if(howmanyout= howmanyin) { int fdin = open(tokens[1],o_rdwr); int fdout = open(tokens[2],o_rdwr); if(dup2(fdin,fdout) >= 0) { tokens[1]=null; tokens[2]=null; execvp(tokens[0],tokens); } else { printf("error in dup2\n"); } } else if(howmanyin== 0) //means have > redirection { int fdout = open(tokens[1],o_rdwr); if(dup2(2,fdout) >= 0) { tokens[2]=null; execvp(tokens[0],tokens); } else { printf("error in dup2\n"); } } else //means have redirection { int fdin = open(tokens[1],o_rdwr); if(dup2(fdin,1) >= 0) { tokens[2]=null; execvp(tokens[0],tokens); } else { printf("error in dup2\n"); } } }
myshell2.c
#include "functions.h" int main() { printf("myshell2>"); pid_t pid,waitpid; //we tried withou allocating memory char *argline = (char *)malloc(max); char **args = (char **)malloc(max); char **args2 =( char **)malloc(max); char **temp = (char **)malloc(max); char *delim="><"; char *delim2=" "; int i,howmany,howmany2,status; while(fgets(argline,max,stdin) != null) { howmany= argcounter(argline,delim);//howmany redirections args=argarray(argline,howmany,args,delim); if (howmany == 1)//means @ myshell 1 { howmany2= argcounter(argline,delim2); if(howmany2 ==1)//checking if command has parameters (like ls -l) { printf("myshell2>"); pid = fork(); if (pid < 0) { perror("error: fork failed.\n"); return -1; } else if(pid == 0) { myexec(args[0],howmany2,delim2); perror("error: child should never arrive here.\n"); } else { waitpid = wait(&status); if (waitpid == -1) { perror("error: waitpid failed.\n"); return -1; } } } else { printf("error: wrong number of arguments!\n");//can't run on myshell 2 return(0); } } //means have redirection (< or >) (i=0; i<howmany; i++) { argarray(args[i],2,args2,delim2);//args2 contains tokens without spaces(delim2) temp[i] = args2[0]; howmany2 = argcounter(args[i],delim2); if(howmany2 > 1) // eg. ls -l should not run here { printf("error: wrong number of arguments!\n");//myshell3 should running return(0); } } printf("myshell2>"); pid = fork(); if (pid < 0) { perror("error: fork failed.\n"); return -1; } else if(pid == 0) { myexecredir(temp,argline,howmany); perror("error: child should never arrive here.\n"); } else { waitpid = wait(&status); if (waitpid == -1) { perror("error: waitpid failed.\n"); return -1; } } } }
thank in advance.
char *temp; memcpy(temp,argline,strlen(argline)); char *pointer = strtok(temp, delim); ...
is wrong, need reserve space malloc
:
size_t len = strlen(argline); char *temp = malloc(len + 1); if (temp == null) return 0; memcpy(temp, argline, len); /* nul-terminate string */ temp[len] = '\0'; char *pointer = strtok(temp, delim); ... free(temp);
or can use non-standard function (but available on many implementations) strdup
:
char *temp = strdup(argline); if (temp == null) return 0; char *pointer = strtok(temp, delim); ... free(temp);
char **args = (char **)malloc(max);
is wrong, if need reserve space n
pointers char
use:
char **args = malloc(sizeof(*args) * n); /* don't cast malloc */
or
char **args = malloc(sizeof(char *) * n);
Comments
Post a Comment