Sto sviluppando un comando shell in C, e ho aproblema quando si utilizza il comando execv. Ho un do while (1) nel main, quindi dovrebbe essere un ciclo infinito, ma se introduco / bin / ls come comando, il prompt mostra i file e le cartelle e poi si ferma.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#define MAX_LENGTH 256
#define DEFAULT_STRING_LENGTH 256
#define MAX_PARAMETERS 16
void initParams(char *** params);
void read_command(char *** params);
void freeParams(char *** params);
void type_prompt();
int comprobarSalir(char ***cadena);
int main(){
int salir = 0;
do{
char ** params;
type_prompt();
fflush(stdout);
initParams (& params);
read_command (& params);
salir = comprobarSalir(& params);
if(comprobarSalir(¶ms)==0){
if(execv(params[0], params) == -1){
printf("%s,%s",params[0],params[1]);
printf("Error al ejecutar el comando " %s": %sn", params [0], strerror(errno));
freeParams (& params);
}
}
}while(1);
}
void read_command(char *** args) {
char input [256], *substr;
int n = 0;
fgets(input , sizeof(input), stdin);
input[strlen(input) -1] = " ";
substr = strtok(input , " ");
if (substr != NULL)
memcpy ((* args)[n], substr , strlen(substr));
else
(*args)[n] = NULL;
n++;
while ((* args)[n-1] != NULL) {
substr = strtok(NULL , " ");
if (substr != NULL)
memcpy ((* args)[n], substr , strlen(substr));
else
(*args)[n] = NULL;
n++;
}
}
void freeParams(char *** params){
int i;
char ** parameter;
for (i=0; i<MAX_PARAMETERS; i++) {
parameter = ((* params) +i);
if (* parameter != NULL) free(* parameter);
}
free(* params);
*params = NULL;
}
void initParams(char *** params) {
int i, j;
char ** parameter;
*params = (char **) malloc(sizeof(parameter) * MAX_PARAMETERS);
for (i = 0; i<MAX_PARAMETERS; i++) {
parameter = (* params) + i;
*parameter = (char*) malloc(DEFAULT_STRING_LENGTH);
for (j = 0; j<DEFAULT_STRING_LENGTH; j++) *((* parameter)+j) = " ";
}
}
void type_prompt(){
char cwd[MAX_LENGTH];
getcwd(cwd, sizeof(cwd));
printf("%s$ ",cwd);
}
int comprobarSalir(char ***cadena){
int salir = 0;
char* exit = "exit";
if(***cadena==*exit){
salir = 1231;
}
return salir;
}
risposte:
2 per risposta № 1execv
sostituisce il processo che lo richiama con un programma diverso.
Poiché il processo corrente sta ora eseguendo un programma diverso (ls
), ovviamente il suo ciclo non continuerà più.
Se si desidera che un processo continui a essere eseguito dopo la chiamata execv
, quindi è necessario utilizzare fork()
creare un processo figlio; controlla se sei il genitore o il bambino e chiama execv
solo nel bambino. A quel punto, se vuoi che il genitore attenda la copia di ls
per finire, puoi usare wait()
nel genitore di farlo, e determinare se il bambino ha avuto successo o fallito.