Почему переменная окружения сбрасывается после использования setenv () - PullRequest
6 голосов
/ 08 августа 2011

Я написал программу на C для Linux, чтобы установить значения переменных среды, используя setenv, но после выполнения, когда я запускаю set или export, сама переменная среды кажется неустановленной. Зачем?

Вот фрагмент кода:

int main()
{
  char *mallocPtr, *callocPtr, *reallocPtr, *memalignPtr, *vallocPtr;
  struct sigaction sa;

  sa.sa_handler=SIGSEGV_handler;
  sigaction(SIGSEGV, &sa, NULL);

  if(setenv("ENV1", "3", 1) == 0)
         printf("ENV1 set to 3\n");
  else
         fprintf(stderr, "setenv failed on ENV1");

Ответы [ 3 ]

13 голосов
/ 08 августа 2011

Переменные среды устанавливаются в контексте вашей программы.

Когда ваша программа завершает работу, вы возвращаетесь в контекст, откуда была запущена ваша программа.

5 голосов
/ 16 августа 2011

Библиотека C рассматривает переменные среды как глобальные настройки, которые вы можете прочитать с помощью getenv и настроить с помощью setenv / putenv, и которые наследуются через вызовы семейства exec, но это удобная фикция.Что касается ядра, переменные окружения являются вторым набором аргументов для main.Это становится понятным, если вы посмотрите на фактический системный вызов execve, лежащий в основе семейства exec.Это его прототип C:

int execve(const char *filename, char *const argv[], char *const envp[]);
                                                     ^^^^^^^^^^^^^^^^^^

Видите этот третий аргумент?Это единственный способ , в котором процесс A устанавливает переменные среды процесса B. 1 Следовательно, единственный время процесс A может устанавливать переменные среды процесса B, когда процесс A запускает процесс B, через fork и execve.

Ваша программа запускается с помощью оболочки, поэтому оболочка должна установить свою копию средыпеременные, но у нее нет возможности отправить изменения обратно в оболочку - точно так же, как у функции C нет возможности изменить значения своих аргументов в вызывающей стороне.

1 Не воспитывать ptrace.

1 голос
/ 25 ноября 2013

На самом деле каждый процесс имеет свой собственный массив envp char.Функция main имеет следующую подпись:

int main(int argc, char *argv[], char *envp[])

Обычно envp родительского объекта наследуется дочерним элементом вниз по иерархии родительский-дочерний.Он никоим образом не передается вверх в иерархии родитель-потомок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...