Указатель, теряющий значение + предупреждение о компиляции execv

91
10

Надеюсь, я не упустил аналогичный вопрос.

Я пытаюсь закодировать собственную мини-оболочку, используя примитивные функции C.

У меня есть что-то, что должно работать, но у меня есть указатель, который делает все ошибки.

Мой указатель adrCmd должен получить строку командного пути из функции searchCmd() и сохранить одно и то же значение в main функции.

Фактически: он указывает на правильное значение на searchCmd(), но не в main().

Здесь код:

    int searchCmd(char* cmd, char* adrCmd){
char* path = getenv("PATH");
if(debug)printf("PATH : %s\n", path);
int nbPath = (compteLettre(path, ':')+1);
char** pathTab = malloc(nbPath*sizeof(char*));
decompose(path, pathTab, 2048, ':');

int i;
char* adr = malloc(sizeof(char*));
for(i=0; i<nbPath; i++){
sprintf(adr, "%s/%s", pathTab[i], cmd);
if(debug)printf(" source : %s \n", adr);

int fs = open(adr, O_RDONLY); // Si on peut ouvrir le fichier, c'est qu'il existe !
if(fs != -1){ // si le fichier existe, on le renvoie;
if(debug){
printf("Commande trouvée dans path ! \n");
printf("%s \n", adr);
}
adrCmd = adr;
printf("%s ?= %s \n",adrCmd, adr );// oui
return 1;
}
}
return 0;
}

/**********************\
Main
\**********************/

int main(int argc, char** argv){
printf("Mini-shell : OK \n");

char cmd[CMDSIZE];
char** splited = malloc(CMDSIZE*sizeof(char*));
char* adrCmd = malloc(sizeof(char*));
char* params;
while(printf("$ : ") && gets(cmd) && (strcmp(cmd, "exit")!=0 && strcmp(cmd, "quit")!=0)){ // On boucle tant que la commande != "exit" ou "quit"

printf("Votre commande : %s \n", cmd);
decompose(cmd, splited, CMDSIZE, ' ');
if(debug)afficheCmd(splited, CMDSIZE);

if(!searchCmd(splited[0], adrCmd)){
printf("Commande n'existe pas, essayez apt-get install %s\n", splited[0]);
}else{
if(debug)printf("Execution de la commande '%s' : \n", adrCmd);
params = splited[1]; // params = array(splited[1], splited[2], ...... )
if(execv(adrCmd, params) == -1){
printf("Erreur d'exection de la commande\n");
}
}

}
printf("Fin du programme %s \n", argv[0]);
return 0;
}

Вот что возвращает выполнение:

$ ./a.out 
Mini-shell : OK
$ : ls /var
Votre commande : ls /var
CMD[0] = ls
CMD[1] = /var
PATH : /usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
source : /usr/lib/lightdm/lightdm/ls
source : /usr/local/sbin/ls
source : /usr/local/bin/ls
source : /usr/sbin/ls
source : /usr/bin/ls
source : /sbin/ls
source : /bin/ls
Commande trouvée dans path !
/bin/ls
/bin/ls ?= /bin/ls
Execution de la commande '' :
Erreur d'exection de la commande

И пока я здесь, когда компилирую, execv возвращает предупреждение:

$ gcc shell.c 
shell.c: In function ‘main:
shell.c:113:4: attention : passing argument 2 of ‘execv from incompatible pointer type [enabled by default]
/usr/include/unistd.h:564:12: note: expected ‘char * const* but argument is of type ‘char *

Что я должен сделать, чтобы этого избежать?

спросил(а) 2014-10-31T20:26:00+03:00 5 лет, 11 месяцев назад
1
Решение
57

C передается по значению. Поэтому, когда это делается

 int searchCmd(char * cmd, char * adrCmd){

adrCmd - это копия того, что было передано. Перезапись копии не изменит того, с чего она была скопирована в вызывающем.

Чтобы исправить это, пропустите адрес adrCmd:

 int searchCmd(char * cmd, char ** padrCmd){

и используйте его так:

    *padrCmd = adr;

Вызовите searchCmd() следующим образом:

  if(!searchCmd(splited[0], &adrCmd)){

и определить и инициализировать adrCmd следующим образом;

  char * adrCmd = NULL;

ответил(а) 2014-10-31T20:37:00+03:00 5 лет, 11 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема