Issue
I'm trying to make a simple command line interface, but i'm having a probleme for parsing commands :
process_t is a structure contient the path of the command with arguments to be stored in the variable argv.
int parse_cmd(char* tokens[], process_t* commands) {
assert(tokens!=NULL);
assert(commands!=NULL);
int position = 0;
int commandNumber = 0;
for(int i=0; tokens[i] != NULL; i++){
if(is_reserved(tokens[i]) == 0 && tokens[i+1] != NULL) continue;
int end = is_reserved(tokens[i]) == 0 ? i+1 : i;
int argc = position;
int count = 0;
process_t newProcess;
char* argv[MAX_CMD_SIZE] = {NULL};
for(argc; argc < end; argc++) {
argv[count] = tokens[argc];
count = count + 1;
}
newProcess.path = tokens[position];
newProcess.argv = argv;
position = i + 1;
commands[commandNumber] = newProcess;
commandNumber = commandNumber + 1;
}
}
int main(int argc, char* argv[]) {
char path[MAX_LINE_SIZE];
char line[MAX_LINE_SIZE];
char* cmdline[MAX_CMD_SIZE];
process_t cmds[MAX_CMD_SIZE];
getcwd(path, MAX_LINE_SIZE);
while (1) {
printf("mini@shell:%s$ ", path);
scanf("%[^\n]%*c", line);
trim(line);
clean(line);
tokenize(line, cmdline);
parse_cmd(cmdline, cmds);
toString(cmds);
break;.
}
return -1;
}
Input: ls -l ; grep ^a
Why the array contain only the value of argv of the last iteration ?
Output :
path : ls => argv = {grep, ^a, (null)} path : grep => argv = {grep, ^a, (null)}
Solution
You're trying to use the block-local array argv
, which is recreated for every command and, what's worse, doesn't even exist any longer after parse_cmd
has returned. An array object with sufficient lifetime has to be used; you can do this by changing
char* argv[MAX_CMD_SIZE] = {NULL};
to
char **argv = calloc(end-position+1, sizeof *argv);
Note that you'd have to free
this object when no longer needed.
Also note that you forgot to return commandNumber;
from parse_cmd
; without that, you have no way of knowing how many commands were found.
Answered By - Armali Answer Checked By - David Marino (WPSolving Volunteer)