execvp не работает с аргументом командной строки

Я работаю над этой программой для запуска команды оболочки, заданной через аргумент командной строки, с использованием системных вызовов execvp() и fork(). Здесь arglist — это двумерный массив, который содержит имя команды и список ее аргументов. Я передаю имя команды в качестве первого аргумента и массив списка аргументов в качестве второго аргумента. Но это не работает. справочная страница execvp() говорит, что по умолчанию данная команда будет искаться в каталогах, определенных переменной PATH, поэтому я передаю только имя команды.

#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>

void executeCommand(char *command,char **arglist){

    int pid;
    int status;

    pid=fork();

    printf("%s %s\n",command,arglist[1]);

    if(pid == -1){
        printf("fork failed\n");
        exit(1);
    }
    else if(pid==0){

        if(execvp(command,arglist) == -1){
            printf("execution of command failed\n");
            exit(1);
        }
        exit(0);
    }
    else {

        while(wait(&status) != pid);

        printf("Parent Exiting\n");
        exit(0);
    }


}


int main(int argc,char **argv){

    char **arglist,*com;
    int i,k=1;

    if(argc>2){
        arglist = (char**)malloc(sizeof(char*)*(argc));
        for(i=0;i<argc-1;i++){
            arglist[i] = (char*)malloc(sizeof(char)*1024);

        }   
        com = (char*)malloc(sizeof(char)*strlen(argv[1]));      

        strcpy(com,argv[1]);
        for(i=1;i<=(argc-1);i++,k++){
            strcpy(arglist[k],argv[i]);

        }
        arglist[k] = NULL ;
        for(i=0;i<argc;i++){
            printf("%s\n",argv[i]);
        }

        executeCommand(argv[1],arglist);



    }

    //printf("%d\n",argc);




    return 0;
}

person dharakk    schedule 29.08.2014    source источник
comment
Итак, какой результат вы получаете? команда не удалась?   -  person Arpit    schedule 29.08.2014
comment
Когда вы говорите, что это не working with command line arguments, вы имеете в виду, что execvp завершается успешно без дополнительных аргументов? Кроме того, поскольку вы упомянули PATH, вы пытались дать ему команду с полным путем?   -  person Vinícius Gobbo A. de Oliveira    schedule 29.08.2014
comment
Кажется, вы также копируете имя команды в arglist, возможно, поэтому оно не работает   -  person Arpit    schedule 29.08.2014
comment
@Arpit Иногда происходит сбой, иногда ошибка сегментации, а иногда просто ничего не происходит. Я думаю, что имя команды должно быть скопировано как первый аргумент в списке аргументов.   -  person dharakk    schedule 29.08.2014
comment
@ViníciusGobboA.deOliveira Да, это работает с жестко закодированными аргументами. Работает просто указание имени команды. Полный путь не требуется   -  person dharakk    schedule 29.08.2014
comment
@DharakKharod: когда вы инициализируете список аргументов, вместо (argc-1) измените его на (argc). Происходит переполнение буфера   -  person Arpit    schedule 29.08.2014
comment
@DharakKharod: А также вместо того, чтобы жестко кодировать инициализацию до 1024, будет лучше, если вы используете strlen (argv [i]). Это сэкономит много памяти.   -  person Arpit    schedule 29.08.2014
comment
@Arpit Да, это сработало! Более того, я инициализировал индекс списка аргументов k с 1 вместо 0. Спасибо!   -  person dharakk    schedule 29.08.2014
comment
Чтобы сделать программу чистой, обязательно добавьте вызовы для освобождения выделенной памяти.   -  person R Sahu    schedule 29.08.2014


Ответы (1)


Вы не выделяете достаточно места для команды, когда делаете

com = (char*)malloc(sizeof(char)*strlen(argv[1]));

поскольку он не освобождает место для терминатора, вам нужно добавить его к результату strlen, как в

com = (char*)malloc(sizeof(char)*(1+strlen(argv[1])));

Еще проще было бы использовать strdup вместо malloc/strcpy. Тогда вам просто нужно сказать

com = strdup(argv[1]);

а также

arglist[k] = strdup(argv[i]);

и удалите все malloc, кроме того, который создает пространство для самого arglist.

person Geoff Reedy    schedule 29.08.2014
comment
Кроме того, вы не должны указывать адрес возврата malloc в C. - person knarf; 29.08.2014