Операционная система UNIX - страница 53

стр.

и putenv(3C):

>#include

>char *getenv(const char *name);

возвращает значение переменной окружения >name, a

>int putenv(const char *string);

помещает переменную и ее значение (>var_name=var_value) в окружение программы.

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

>#include

>#include

>#include


>main(int argc, char *argv[]) {

> char *term;

> char buf[200], var[200];

> /* Проверим, определена ли переменная TERM */

> if ((term = getenv("TERM")) == NULL)

>  /* Если переменная не определена, получим от пользователя ее значение и

>     поместим переменную в окружение программы */

> {

>  printf("переменная TERM не определена, введите значение: ");

>  putenv(var);

> } else

>  /* Если переменная TERM определена, предоставим пользователю возможность

>     изменить ее значение, после чего поместим ее в окружение процесса */

> {

>  printf("TERM=%s. Change? [N]", getenv("TERM"));

>  gets(buf);

>  if (buf[0] == 'Y' || buf[0] == 'y') {

>   printf("TERM=");

>   gets{buf);

>   sprintf(var, "TERM=%s", buf);

>   putenv(var);

>   printf("new %s\n", var);

>  }

> }

>}

Сначала программа проверяет, определена ли переменная >TERM. Если переменная >TERM не определена, пользователю предлагается ввести ее значение. Если же переменная >TERM определена, пользователю предлагается изменить ее значение, после чего новое значение помещается в окружение программы.

Запуск этой программы приведет к следующим результатам:

>$ а.out

>TERM=ansi. Change? [N]y

>TERM=vt100

>new TERM=vt100

>$

К сожалению, введенное значение переменной будет действительно только для данного процесса и порожденных им процессов: если после завершения программы a.out вывести значение >TERM, то видно, что оно не изменилось:

>$ echo $TERM

>ansi

>$

Наследование окружения программы мы обсудим в разделе "Создание и управление процессами" далее в этой главе.

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

Обычно при запуске программы на выполнение из командной строки shell автоматически устанавливает для нее три стандартных потока ввода/вывода: для ввода данных, для вывода информации и для вывода сообщений об ошибках. Начальную ассоциацию этих потоков (их файловых дескрипторов) с конкретными устройствами производит терминальный сервер (в большинстве систем это процесс getty(1M)), который открывает специальный файл устройства, связанный с терминалом пользователя, и получает соответствующие дескрипторы. Эти потоки наследует командный интерпретатор shell и передает их запускаемой программе. При этом shell может изменить стандартные направления (по умолчанию все три потока связаны с терминалом пользователя), если пользователь указал на это с помощью специальных директив перенаправления потока (>, <, >>, <<) см. главу 1, раздел "Пользовательская среда UNIX"). Раздел "Группы и сеансы" внесет окончательную ясность в этот вопрос при описании управляющего терминала.

Такой механизм позволяет программисту не задумываться о местонахождении пользователя, и в то же время обеспечить получение и передачу данных именно запустившему данную программу пользователю.

Завершая разговор о запуске программ, заметим, что при компиляции программы редактор связей устанавливает точку входа в программу, указывающую на библиотечную функцию _start(). Эта функция инициализирует процесс, создавая кадр стека, устанавливая значения переменных и, в конечном итоге, вызывая функцию main().

Завершение C-программы

Существует несколько способов завершения программы. Основными являются возврат из функции main()[17] и вызов функций