Мне дали этот код в классе:
int main(int argc, char **argv)
{
if (argc)
{
return 1;
}
puts(argv[3]);
return 0;
}
Теперь я должен написать вторую программу, которая выполнит это и заставит печатать «Hello World!». Поэтому мне нужно найти способ передать аргументы (я полагаю, с помощью execv), оставив argc равным 0.
Вот что у меня есть на данный момент:
int main()
{
pid_t pid = fork();
if (pid == 0)
{
char *argv[] = { "filepath", "placeholder",
"placeholder", "Hello World!" };
execv("filepath", argv);
exit(0);
}
else
{
waitpid(pid, 0, 0);
}
return 0;
}
Это будет работать в Linux.
Я попробовал исходное предложение mbj передать 0 в массив аргументов, что, к сожалению, не сработало. Однако, если я поставлю 0 в качестве первого аргумента, argc станет 0, но тогда я получу вывод «LC_MEASUREMENT = de_DE.UTF-8» при попытке распечатать аргументы. Поиск в Google мне тоже не помог.
Я здесь в полной растерянности, поэтому любая помощь приветствуется.
В Linux добавлю в пост





Хорошо, теперь я понял это после некоторых собственных экспериментов.
Поскольку передача массива, который начинается с NULL (0) в execv, приводит к тому, что программа распечатывает LC_MEASUREMENT=de_DE.UTF-8, я понял, что это должно означать, что argv[3] ссылается на элемент в процессе окружающая обстановка (LC_MEASUREMENT - одна из переменных среды, используемых для настройки локали). настройки в Linux).
execvПоскольку execv скопирует текущую среду в новую программу, нам просто нужно изменить среду и поместить строку "Hello World!" в нужное место перед вызовом execv. Оказывается, печатаемая строка - это строка, на которую указывает индекс 2 среды.
Чтобы получить доступ к текущей среде, нам нужно объявить переменную environ вне main:
external char **environ;
int main()
{
...
А затем сделайте это перед вызовом execv:
char *argv[] = { NULL };
environ[2] = "Hello world!";
execv("filepath", argv);
execveВместо объявления external char **environ и изменения текущей среды перед вызовом execv мы можем использовать функцию execve, которая позволяет нам передать новый массив строк для использования в качестве среды для программы:
char *argv[] = { NULL };
char *envp[] = { "foo", "bar", "Hello World!", NULL };
execve("filepath", argv, envp);
Как показано в приведенном выше фрагменте кода, "Hello World!" должен иметь индекс 2 среды, независимо от того, какой метод мы используем.
Причина, по которой это работает, заключается в том, что существует стандарт того, как аргументы командной строки и среда размещаются в памяти процесса при выполнении программы: массив указателей символов среды помещается сразу после массива аргументов командной строки.
Поскольку эти массивы заканчиваются записью NULL, это будет выглядеть так:
+---------+---------------------------------------+
| Args | Environment |
+---------+---------+---------+---------+---------+
| NULL | envp[0] | envp[1] | envp[2] | NULL |
+---------+---------+---------+---------+---------+
^ ^ ^
| | |
argv[0] argv[1] ... argv[3]
Я надеюсь, что искусство ASCII поможет вам понять, почему argv[3] означает то же самое, что и environ[2], когда мы выполняем такую программу.
Спасибо, это решение сработало! Спасибо за отличное объяснение, сделав его действительно легким для понимания.
В какой операционной системе это будет работать?