Reputation: 29
When my code looks like this I can run ls -la perfectly.
char * ls_args[3] = {"ls","-la",NULL};
pid_t c_pid, pid;
int status;
c_pid = fork();
if (c_pid == 0){
/* CHILD */
printf("Child: executing ls\n");
//execute ls
execvp( ls_args[0], ls_args);
//only get here if exec failed
perror("execve failed");
}else if (c_pid > 0){
/* PARENT */
if( (pid = wait(&status)) < 0){
perror("wait");
_exit(1);
}
printf("Parent: finished\n");
}else{
perror("fork failed");
_exit(1);
}
}
but when I do this, it doesn't work and it is so confusing becuase when I read in ls from the line and pass it to execvp isnt it the same thing as ls_args[0]? but it doesnt work this way. any help would be great thank you
arguments[count] = NULL;
pid_t c_pid, pid;
int status;
c_pid = fork();
if (c_pid == 0){
/* CHILD */
printf("Child: executing ls\n");
//execute ls
execvp( arguments[0], arguments);
//only get here if exec failed
perror("execve failed");
}else if (c_pid > 0){
/* PARENT */
if( (pid = wait(&status)) < 0){
perror("wait");
_exit(1);
}
printf("Parent: finished\n");
}else{
perror("fork failed");
_exit(1);
}
}
what is in arguments[0] is "ls". also when I check the lengths of each of these and compare them as long as the string inside it is the same thing.
my complete code
int main(){
char *line;
int quit = 1;
char **arguments;
char *directory;
int count = 0;
char *comand = "ls";
int done = 1;
printf("\n\n\n\n\n\n\nLinux Shell: \nCreated by: Zach Adams\n\n");
//while this is one it will keep looping
while(1){ //will run until user enters quit
done = 1;
count = 0;
print_shell_name();
line = (char *)malloc(sizeof(line));
arguments = (char **)malloc(sizeof(char*));
line = fgets(line,MAX,stdin);
quit = strncmp(line,"quit",4);
if(quit == 0)
exit(0);
int i = 0; //parsing line
char *p = strtok(line, " "); //will save the string up to the token entered
free(line);
while(p!= NULL){
arguments[i++] = p; //putting the command or argument into an array of arguments
p = strtok(NULL," "); //null is a pointer to the first argument and continues to scan where prev call ends until it gets to token again
count++;
}
p = strtok(arguments[count-1], "\n"); //get the new line character off of the end
arguments[count-1] = p;
if((strncmp(arguments[0],"cd",2)==0) || (strncmp(arguments[0],"clr",3)==0) //run internal commands
|| (strncmp(arguments[0],"dir",3) ==0) || (strncmp(arguments[0],"environ",7)==0) || (strncmp(arguments[0],"echo",4)==0)
|| (strncmp(arguments[0],"help",4)==0) || (strncmp(arguments[0],"pause",5)==0)){
execute(arguments,count); //execute internal commands
}else if(arguments[0] == NULL){
printf("NULL arg");
}else{
//char * ls_args[3] = {"ls","-la",NULL};
arguments[count] = NULL;
pid_t c_pid, pid;
int status;
c_pid = fork();
if (c_pid == 0){
/* CHILD */
printf("Child: executing ls\n");
//execute ls
execvp( arguments[0], arguments);
//only get here if exec failed
perror("execve failed");
}else if (c_pid > 0){
/* PARENT */
if( (pid = wait(&status)) < 0){
perror("wait");
_exit(1);
}
printf("Parent: finished\n");
}else{
perror("fork failed");
_exit(1);
}
}
free(arguments);
}
return 0;
}
Upvotes: 0
Views: 132
Reputation: 1
This code destroys the line
variable you're using strtok()
on:
char *p = strtok(line, " "); //will save the string up to the token entered
free(line);
When you call
strtok(NULL," ")
later on, strtok()
is still trying to parse line
, which has been freed.
Upvotes: 1