2012-05-22 25 views
5

Estoy construyendo un shell y estoy teniendo algunos problemas con el sistema llamado 'execvp'. Vi algunas otras preguntas sobre este tema, pero fueron vagas y no parecían estar completamente abordadas (quien hizo las preguntas no proporcionó mucha información y no obtuvo buenas respuestas).Construyendo un caparazón C. execvp devuelve el error 'No such file'. crear una matriz argv sobre la marcha con malloc

Obviamente tengo mi propia línea de comandos y estoy leyendo la entrada del usuario a partir de la entrada estándar como

mysh some/path $ ps -a 

y estoy construyendo una matriz args como char ** y la matriz en sí funciona (creo) ya cuando imprimo los valores dentro de mi función se muestra

args[0] = 'ps' 
args[1] = '-a' 
args[2] = '(null)' 

Por lo tanto, llamo tenedor y execvp (CMND, args) dentro de mi proceso, donde CMND es "PS" y args es como antes, y perror etc.

Obtengo

'Error: no such file or directory.' 

¿Debo poner en la variable $ PATH? ¿Estoy haciendo algo más loco?

Aquí está mi código para generar el args matriz:

char ** get_args(char * cmnd) { 
int index = 0; 
char **args = (char **)emalloc(sizeof(char *)); 
char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy,cmnd,strlen(cmnd)); 
char * tok = strtok(copy," "); 
while(tok != NULL) { 
    args[index] = (char *) emalloc(sizeof(char)*(strlen(tok)+1)); 
    strncpy(args[index],tok,strlen(tok)+1); 
    index++; 
    tok = strtok(NULL," "); 
    args = (char**) erealloc(args,sizeof(char*)*(index+1)); 
} 
args[index] = NULL; 
return args; 
} 

(emalloc y erealloc son sólo malloc y realloc con verificación de errores incorporada)

Entonces yo hacer esto:

void exec_cmnd(char*cmnd, char**args) { 
pid_t pid; 
if((pid=fork())==0) { 
    execvp(cmnd, args); 
    perror("Error"); 
    free(args); 
    free(cmnd); 
    exit(1); 
} 
else { 
    int ReturnCode; 
    while(pid!=wait(&ReturnCode)) { 
     ; 
    } 
} 
} 

Y como dije antes, cuando se llama a execvp dentro de mi proceso falla cuando proporciono cualquier argumento pero funciona sin ellos (es decir, cuando argv == {'ps', NULL})

Si necesita más información, no dude en preguntar. Necesito resolver esto.

Respuesta

6

Se piensa que ha pasado la línea de comando conjunto en primer argumento de execvp

hay que separar primer token (nombre de la orden) de cmnd pasar como primer argumento de execvp

Se le puede llamar como

execvp(args[0], args);

+0

Esto es exactamente correcto. Si desea ejecutar 'ps -a', debe llamar a' execvp ("ps", {"ps", "-a", NULL}) '. – caf

+0

ack. palma a la frente. Sí, eso fue, gracias. :) – matchdav

+0

navaja de frikkin ockham – matchdav

1

observar de paso que tiene una cadena no terminada como resultado de:

char * copy = (char *) emalloc(sizeof(char)*(strlen(cmnd))); 
strncpy(copy, cmnd, strlen(cmnd)); 

strncpy() no deja de funcionar cuando lo usa así. También necesita asignar un byte más para el nulo. Considere usar strdup() si está disponible para usted. Si no, considere escribirlo. Esta mala asignación es un problema incluso con las versiones de comprobación de errores de emalloc() y erealloc().

+1

O de acuerdo con el tema, use (o implemente y use) 'estrdup()'. –

+0

Voy a hacer eso totalmente. – matchdav

+0

Lo estoy haciendo ahora mismo, ejecutando vim desde mi caparazón. – matchdav

Cuestiones relacionadas