I've gotta do a shell simulator in C where some commands are mandatory, I'm placing the code here
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#define ARRAYMAX 512
char *entrada = NULL;
size_t linha_tam = 0;
int i = 0;
char* token;
char* array[ARRAYMAX];
void help(){
printf("SHELL DESENVOLVIDA POR:\n ADERBAL NEVES CALMETO JÚNIOR\n GUILHERME DE CASTRO PAOLUCCI PAIVA\n");
printf("PARA SAIR DIGITE q\n");
}
void tokens(void *ent){
token = strtok(ent, "\n ");
while(token != NULL){
array[i ] = token;
token = strtok(NULL, "\n ");
}
array[i] = NULL;
}
void exec(){
int *a;
int pid = fork();
if(pid != 0){
waitpid(-1, a, 0);
}else{
if(execvp(array[0], array) == -1){
printf("%s", array[0]);
perror("Comando inválido");
}
}
}
int main(){
printf("Seja bem-vindo!\nDigite h para ajuda\n");
while(1){
printf(">");
getline(&entrada, &linha_tam, stdin);
if(strcmp(entrada, "\n") == 0){
printf("Insira um comando\n");
continue;
}
tokens(entrada);
if(strcmp(array[0], "q") == 0){
return 0;
}else if(strcmp(array[0], "h") == 0){
help();
continue;
}else{
exec();
printf("%s", array[0]);
}
}
}
the issue is, if I try to call "ls" right after starting the program, it works fine, but when I try to call "help" then "ls", the program crashes saying
ls: cannot access 'ls': no such file or directory
that's a error native from the lib, not written by me I've tried to put some kinds of prints right on the "else" that comes first on the "ls" function but it's not printed, so, I've got no idea of what's happening
CodePudding user response:
Move the global i
variable to the local function tokens
. As you never reset it to 0, you add more and more entries in array
.
void tokens(void *ent){
int i = 0;
token = strtok(ent, "\n ");
while(token != NULL){
array[i ] = token;
token = strtok(NULL, "\n ");
}
array[i] = NULL;
}
CodePudding user response:
There are a lot of issues (per comments) but the easiest solution for the question asked is to change the variable i
from global to a (loop) local scope in tokens()
. This also also eliminates the global token
variable. Unrelated but I also added bounds check for array
:
void tokens(char *ent) {
for(int i = 0; i < ARRAYMAX; i ) {
array[i] = strtok(i ? NULL : ent, "\n ");
if(!array[i]) break;
}
array[ARRAYMAX - 1] = NULL;
}