Это на самом деле очень просто. Вы уже знаете, что ваши аргументы - это список char *
, оканчивающийся указателем NULL. Аналогично, среда - это просто список char *
, оканчивающийся указателем NULL. Условно значения в списке имеют вид VARNAME=var-value
, хотя вы можете передавать другие форматы, если хотите.
Итак, возьмем простой случай:
#include <unistd.h>
#include <stdio.h>
int main(void)
{
char *argv[] = { "/bin/sh", "-c", "env", 0 };
char *envp[] =
{
"HOME=/",
"PATH=/bin:/usr/bin",
"TZ=UTC0",
"USER=beelzebub",
"LOGNAME=tarzan",
0
};
execve(argv[0], &argv[0], envp);
fprintf(stderr, "Oops!\n");
return -1;
}
В этом примере программа будет запускаться /bin/sh
с аргументами -c
и env
, что означает, что оболочка будет запускать программу env
, найденную в ее текущем PATH. Среда здесь содержит 5 значений в ортодоксальном формате. Если вы измените env
на date
(или env; date
), вы увидите, например, эффект настройки TZ. Когда я запускаю это на моей машине MacOS X, вывод:
USER=beelzebub
PATH=/bin:/usr/bin
PWD=/Users/jleffler/tmp/soq
TZ=UTC0
SHLVL=1
HOME=/
LOGNAME=tarzan
_=/usr/bin/env
В оболочку добавлены переменные окружения SHLVL
, _
и PWD
к тем, которые я установил явно в вызове execve()
.
Вы также можете делать более причудливые вещи, например копировать в некоторые другие переменные среды из вашей подлинной среды, где они не конфликтуют с теми, которые вы хотите явно установить. Вы также можете играть в такие игры, как наличие двух значений для одной переменной в среде - какое из них вступает в силу? И вы можете играть в игры с именами переменных, которые содержат пробелы (оболочке это не очень нравится) или записи, которые вообще не соответствуют нотации 'varname = value' (без знака равенства).