它应该是一个无限循环,但它在execv之后停止

时间:2016-12-20 00:11:58

标签: c loops execv

我正在用C开发一个shell命令,使用命令execv时遇到问题。我在main中有一个while(1),所以它应该是一个无限循环,但是如果我将/ bin / ls作为命令引入,则提示显示文件和文件夹,然后停止。

#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;
}

1 个答案:

答案 0 :(得分:2)

execv用不同的程序替换调用它的进程。

由于当前进程现在正在运行另一个程序(ls),当然它的循环将不再继续。

如果您希望在调用execv后继续运行流程,则需要使用fork()来创建子流程;检查您是父母还是孩子,并仅在孩子中致电execv。此时,如果您希望父级等待ls的副本完成,您可以在父级中使用wait()来执行此操作,并确定子级是成功还是失败。