2017-06-20 1 views
0

Je dois faire un shell personnalisé comme un projet scolaire et je frappe un mur avec ceci:exec() erreur de retour pour toute commande

int exec_shell(char **argv) // 
{ 
    if (execve(argv[0], (char **)argv , NULL)==-1) //if an error occurs 
    { 
      printf("Commande invalide : %s\n", argv[0]); 
      fflush(stdout);//vide le buffer 
      exit(0); 
      return -1; 
    } 

    return 0; 
} 

Il est censé être très simple - vous mettre dans un commande sous forme de chaîne et exec appelle la commande. Cependant, il renvoie toujours une erreur.

Qu'est-ce que je fais mal?

Voici le seul avertissement:

primitives.c: 25: 30: avertissement: conversion de dépréciée constante chaîne 'char *' [-Wwrite-strings]

+2

Qu'est-ce que la ligne 25 de votre code? C'est de là que vient l'avertissement. – FKEinternet

+1

Le cast '(char **)' est inutile vu l'argument 'char ** argv'. N'utilisez pas de moules inutiles. Qu'y a-t-il dans 'argv [0]'? Vous n'êtes pas censé passer un pointeur nul en tant qu'argument d'environnement. Les processus ont droit à un environnement minimal - et vous devez passer un pointeur valide vers une liste vide plutôt qu'un pointeur nul ('char * empty [] = {0};' et passer 'empty' à la place de' NULL'). Si vous avez coché 'errno' (ou utilisé perror()' avant d'appeler 'printf()'), vous voudriez voir 'EINVAL' ou' Invalid argument' comme condition d'erreur. En outre, les erreurs doivent normalement être signalées sur 'stderr', pas sur' stdout'. –

+0

Veuillez lire cette spécification pour execve api. https: //linux.die.net/man/2/execve –

Répondre

0

Étape: 1

/* myecho.c */ 

#include <stdio.h> 
#include <stdlib.h> 

int 
main(int argc, char *argv[]) 
{ 
    int j; 

    for (j = 0; j < argc; j++) 
     printf("argv[%d]: %s\n", j, argv[j]); 

    exit(EXIT_SUCCESS); 
} 

Programme Compile: gcc -o myecho.c myecho

étape: 2

/* execve.c */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int 
main(int argc, char *argv[]) 
{ 
    char *newargv[] = { NULL, "hello", "world", NULL }; 
    char *newenviron[] = { NULL }; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    newargv[0] = argv[1]; 

    if (execve(argv[1], newargv , newenviron) == -1) //if an error occurs 
    { 
      printf("Commande invalide : %s\n", argv[0]); 
      fflush(stdout);//vide le buffer 
      exit(0); 
      return -1; 
    } 
} 

programme de compilation: gcc -o exec execve.c

étape: 3 // appel final

./execve ./myecho

étape: observer la sortie.

+0

'perror()' ne se fait jamais appeler. – alk

+0

Vous avez raison. selon votre suggestion, il a été modifié. Merci. –

0

passer un environnement vide soit définie et passe

char * env[] = { NULL }; 

comme troisième paramètre à execve() de ce type

execve(argv[0], argv, env) 

ou utiliser un composé littéral en faisant

execve(argv[0], argv, (char*[]){NULL}) 

également la membres de la famille de fonctions exec*()ne retour en cas d'erreur, de sorte que le code environnant pourrait ressembler à ceci:

int main(void) 
{ 

    ... 

    execve(argv[0], argv, (char*[]){NULL}); 
    perror("execve() failed"); 

    return EXIT_FAILURE; /* include stdlib.h to have this macro available */ 
} 
0

[RESOLU] Hé, je voudrais vous remercier tous pour votre réponse. Cela m'a aidé à mieux comprendre ce qui n'allait pas et j'ai trouvé une réponse here. Le principal problème était que le chemin n'était pas correct.