Reputation: 3
I want to run the following command "ls | date" but whenever i isolate the ls and the date, they don't execute using execvp.
Problem:
Isolated:ls
ls: impossible to acess 'ld-linux-x86-64.so.2': Unknown directory or file
ls: impossible to acess 'ld-linux-x86-64.so.2': Unknown directory or file
Isolated: date
ls: impossible to acess 'date': Unknown directory or file
In the code, i want to check the ";" but when i check " " && "|" it isolates the parameters i want... but they don't run.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
char command_line[256]="ls | date";
char *ptr_current_command;
char *saveptr1;
char *saveptr2;
char *saveptr3;
char *ptr_current_parameter;
char *ptr_current_parameter2;
char *str[256];
int i=0;
int wait_child;
pid_t pid;
//Uses Strtok to recognize token ";"
ptr_current_command=strtok_r(command_line, ";", &saveptr1);
while (ptr_current_command != NULL) {
//printf("current_command: %s\n", ptr_current_command);
//Uses Strtok to recognize token " "
ptr_current_parameter=strtok_r(ptr_current_command, " ", &saveptr2);
while(ptr_current_parameter != NULL){
//printf("\tcurrent_parameter: %s\n", ptr_current_parameter);
//Uses Strtok to recognize token "|"
ptr_current_parameter2=strtok_r(ptr_current_parameter, "|", &saveptr3);
while(ptr_current_parameter2 != NULL){
printf("\t\tIsolei: %s\n", ptr_current_parameter2);
str[i]=ptr_current_parameter2;
i++;
//Closes token by token until final NULL of "|"
ptr_current_parameter2=strtok_r(NULL, "|", &saveptr3);
}
pid=fork();
if (pid < 0) { perror("fork"); exit(errno); }
if (pid == 0){
execvp(str[0], str);
perror("execvp"); exit(errno);
}
if (wait_child)
waitpid(pid, NULL, 0);
//Fecha Delimitador Espaço
ptr_current_parameter=strtok_r(NULL, " ", &saveptr2);
}
//Closes token by token until final NULL of ";"
ptr_current_command=strtok_r(NULL, ";", &saveptr1);
}
return 0;
}
Upvotes: 0
Views: 337
Reputation: 223689
Two issues here.
First, you aren't building str
correctly. It has to contain a NULL
pointer value after the last parameter, otherwise execvp
won't know which option is the last.
Since str
is uninitialized, the contents of any element beyond the ones you set in the inner are undefined. Attempting to read those elements (as execvp
does) invokes undefined behavior.
After the inner loop, you need to set the current index to NULL
.
The second issue is that you don't reset i
to 0 when entering the inner loop. So even if the first command works, the second one won't because it keeps writing past the parameters for the first command.
Your inner loop should look like this after the fix:
i = 0; // reset i for each command
while(ptr_current_parameter2 != NULL){
printf("\t\tIsolei: %s\n", ptr_current_parameter2);
str[i]=ptr_current_parameter2;
i++;
//Closes token by token until final NULL of "|"
ptr_current_parameter2=strtok_r(NULL, "|", &saveptr3);
}
str[i] = NULL; // terminate the list
Upvotes: 1