2016-12-20 4 views
0

Я разрабатываю команду оболочки в C, и у меня есть проблема при использовании команды execv. Я делаю while (1) в основном, поэтому он должен быть бесконечным циклом, но если я введу/bin/ls в качестве команды, в подсказке будут показаны файлы и папки, а затем она остановится.Предполагается, что это бесконечный цикл, но он останавливается после execv

#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(&params)==0){ 

     if(execv(params[0], params) == -1){ 
      printf("%s,%s",params[0],params[1]); 
      printf("Error al ejecutar el comando ' %s': %s\n", 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] = '\0'; 
    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) = '\0'; 
    } 
} 

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; 
} 
+0

'void read_command (char *** args) {' ... Мне это нравится !!! BTW: Кажется, вам нравятся недействительные функции, не так ли? – wildplasser

+0

Пожалуйста, отформатируйте свой код, прежде чем публиковать его здесь. Одна из программ, которая делает это, - «indent». –

+0

Извините роланд, я новичок. В следующий раз я последую за советом. –

ответ

2

execv заменяет процесс, который вызывает его с помощью другой программы.

Поскольку текущий процесс теперь запускает другую программу (ls), его цикл больше не будет продолжаться.


Если вы хотите, чтобы процесс продолжает работать после вызова execv, то вам нужно использовать fork() для создания дочернего процесса; проверьте, являетесь ли вы родителем или ребенком, и вызывайте execv только у ребенка. В этот момент, если вы хотите, чтобы родитель подождал, пока закончится копия ls, вы можете использовать wait() в родительском для этого, и определить, удалось ли ребенку сменить или не удалось.

+0

Итак ... это сумасшедшая команда оболочки. Как я могу вернуться к основной программе и прочитать команды, пока вход «exit» –

+1

Этот ответ, как отредактирован, сообщает вам, как это сделать уже: вы * не * используете 'execv' непосредственно в основном процессе (поскольку его использование выходит из вашей программы); вместо этого вы используете 'fork()' для создания копии себя и 'execv()' только в копии, а затем 'wait()' ing, чтобы выполнить копию и выяснить, удалось ли она выполнить. –