Леди и джентельмены. У меня проблема при использовании execvp внутри программы C для копирования файлов, она просто не хочет работать. Команды tar и mv также не работают, и я предполагаю, что все, что связано с созданием файлов, также имеет какую-то проблему. Странно то, что такие команды, как ls (с его параметрами) и echo, также работают при вызове с помощью execvp.
Вот рассматриваемый код:
int main () {
char *curr_working_dir, *input, *inputCpy, *command, **args;
struct timeval start, end, duration;
system("clear");
while(1) {
curr_working_dir = getcwd(NULL, 0);
printf("%s $ ", curr_working_dir);
free(curr_working_dir);
fgets(input, 200, stdin);
input[strlen(input) - 1] = '\0';
inputCpy = cpyInput(input);
command = strtok(input, " ");
if(!(strcmp(command, "exit"))) {
break;
}
else if(!(strcmp(command, "cd"))) {
command = strtok(NULL, " ");
struct stat s;
if(!stat(command, &s) && S_ISDIR(s.st_mode)) {
chdir(command);
}
else {
chdir(getenv("HOME"));
}
free(inputCpy);
command = NULL;
}
else {
int pid = fork();
if(pid < 0) {
printf("Error al crear el proceso hijo\n");
}
else if(pid == 0) {
args = constructArgs(inputCpy);
execvp(command, args);
printf("execvp fallo: %s\n", strerror(errno));
}
else {
gettimeofday(&start, NULL);
wait((int*)NULL);
gettimeofday(&end, NULL);
timersub(&end, &start, &duration);
printf("Duracion del comando: %ld.%06ld\n", (long int)duration.tv_sec, (long int)duration.tv_usec);
free(inputCpy);
command = NULL;
}
}
}
return 0;
}
Вот некоторые вспомогательные функции, которые я использую в своей программе:
char **constructArgs(char *input) {
int i = 0;
char *argActual, **args;
argActual = strtok(input, " ");
args = malloc(sizeof(char *));
while(argActual != NULL) {
args[i] = malloc((strlen(argActual) + 1) * sizeof(char));
strcpy(args[i], argActual);
i += 1;
args = realloc(args, (i + 1) * sizeof(char *));
argActual = strtok(NULL, " ");
}
args[i] = NULL;
return args;
}
char *cpyInput(char *input) {
char *cpy;
cpy = malloc((strlen(input) + 1) * sizeof(char));
strcpy(cpy, input);
return cpy;
}
Я используюstructArgs для создания массива аргументов для конкретной программы, которую я буду вызывать через execvp, анализируя входную строку, содержащую команды с ее аргументами. Я могу менять каталоги, вызывать эхо, просматривать содержимое каталогов, но когда я пытаюсь запустить cp, mv или tar, ничего не происходит.
Я проверил, что отправляю правильную информацию в execvp; взгляните на это, например:
допустим, у меня есть файл в /home/john/r1.sav, и я хочу скопировать его в другую папку, расположенную в /home/john/anotherfolder. Я отладил свою программу, и вот что я получаю в качестве содержимого аргументов команды и аргументов прямо перед вызовом execvp:
команда = КП
аргументы [0] = cp
args[1] = /home/john/r1.sav
args[2] = /home/john/anotherfolder
Это ожидаемые входные данные для execvp, если вы хотите использовать через него cp. Но отказывается что-либо делать. execvp получает в качестве первого аргумента имя программы, которая должна быть выполнена, и массив аргументов, которые потребуются программе, причем первый аргумент в массиве аргументов также имеет имя программы, что и я делаю. Все отлично работает с ls или echo, но не с cp, mv или tar.
Заранее благодарим вас за любую помощь, которую вы можете оказать по этой своеобразной проблеме.
NULL
вgetcwd
как и вы, является расширением в glibc, и что ввод, который вы получаете отfgets
на самом деле может не заканчиваться новой строкой, например, если пользователь вводит 199 символов (в вашем случае). Кроме того,sizeof(char)
определяется в спецификации C как всегда1
. А в glibc есть функцияstrdup
, так что вам не нужно вашаcpyInput
функция. - person Some programmer dude   schedule 18.02.2015execvp
? С какой ошибкой? - person Some programmer dude   schedule 18.02.2015wait
, а также как проверить, что он возвращает (вы знаете, это может привести к сбою). Что касается этого вызоваwait
, не повторяйте типNULL
. - person Some programmer dude   schedule 18.02.2015