#c #exec
Вопрос:
В настоящее время я работаю над проектом, в котором мне нужно использовать execvp. У меня возникли проблемы с использованием этого, потому что я не могу заставить его работать, так что, возможно, это как-то связано с тем, как я передаю аргументы.
Мне нужно выполнить программу, предоставленную нам нашими профессорами.
Аргументами для выполнения этой программы являются:
$ ./bin/aurrasd-filters/aurrasd-gain-double < samples/sample-1-so.m4a > output.m4a
Вот как я пытался привести аргументы, чтобы это сработало:
int main () {
char *agr2[] = {"./bin/aurrasd-filters/aurrasd-gain-double", "<", "samples/sample-1-so.m4a", ">", "output.m4a", NULL};
if (!fork()) {
execvp(*agr2, agr2);
}
else {
wait(NULL);
printf("Terminated"n);
}
return 0;
}
Поместило бы это все аргументы в правильное место? Кажется, я не могу понять, в чем ошибка.
Комментарии:
1. Я думаю, что ваша проблема в том, что
execvp
не реализовано перенаправление ввода-вывода, поэтому аргументы<
и>
и их аргументы передаются непосредственно программе как часть ее аргументов, а это не то, что она ожидает. Измените./bin/aurrasd-filters/aurrasd-gain-double
/bin/echo
, чтобы увидеть это своими глазами. Это не ответ, потому что исправление зависит от более подробной информации о том, что вас просят сделать для вашего задания; Я больше не могу вам помочь без полной расшифровки инструкций, которые вам были даны.2. Привет, сработало бы, если бы я использовал execv() вместо этого? Из того, что я понимаю, это позволило бы мне сделать это правильно?
3.Нет, ни одна из функций, имя которой начинается с
exec
, не реализует перенаправление ввода-вывода.system
делает (вроде того), но для этого требуется одна строка аргумента, а не вектор аргументов, и он сам разветвляется, так что вполне вероятно, что вы не должны его использовать. Я на самом деле держу пари, что цель задания-научить вас вручную выполнять перенаправление ввода-вывода, что слишком большой вопрос для этого сайта. Опять же, мне нужно увидеть полную расшифровку инструкций, которые вам дали, чтобы помочь еще больше.4. Если вы хотите самостоятельно обработать перенаправление ввода/вывода, вам нужно будет использовать
pipe
в сочетании с одним изdup
системных вызовов, чтобы stdin и stdout ссылались на нужные файлы. Т. Е. вам нужно будет сделать то же самое, что делает оболочка.5. @zwol Большое вам спасибо, я ничего не знал о перенаправлении ввода-вывода.. потратив некоторое время на чтение, я наконец-то смог сделать то, что хотел.
Ответ №1:
Что мне нужно было сделать, так это перенаправить stdout и stdin. <
и >
не были аргументами в пользу исполняемого файла, как я думал.
Это выглядело бы примерно так:
int main () {
char *arg[] = {"./bin/aurrasd-filters/aurrasd-gain-double", NULL};
char *input = "samples/sample-1-so.m4a";
char *output = "output.m4a";
if (!fork()) {
int input_f;
if ((input_f = open(input, O_RDONLY)) < 0) {
perror("Error opening input file");
return -1;
}
dup2(input_f, 0);
close(input_f);
int output_f;
if ((output = open(output, O_CREAT | O_TRUNC | O_WRONLY)) < 0) {
perror("Error creating output file");
return -1;
}
dup2(output_f, 1);
close(output_f);
execvp(*arg, arg);
_exit(0);
}
else {
wait(NULL);
}
return 0;
}
Как упоминалось выше @zwol, нам нужно обработать перенаправление ввода-вывода, я делаю это с помощью dup2()
функции, устанавливая входной файл как stdin и создавая выходной файл и устанавливая его как stdout.
Это сработало для меня, может быть, это поможет кому-то в будущем..