Массив длинных опций состоит из ряда структур типа
struct option
, в каждой из которых описано требуемое поведение длинной опции. Массив должен заканчиваться структурой, содержащей все нули.
Структура длинной опции определена в заголовочном файле getopt.h и должна подключаться с помощью константы
_GNU_SOURCE
, определенной для того, чтобы разрешить использование функции
getopt_long
.
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
Элементы
структуры описаны в табл. 4.1.
Таблица 4.1.
Параметр опции
Описание
name
Название длинной опции. Сокращения будут приниматься до тех пор, пока они не создадут путаницы при определении названий других опций
has_arg
Принимает ли эта опция аргумент. Задайте 0 для опций без аргументов, 1 для опций, у которых должно быть значение, и 2 для опций с необязательным аргументом
flag
Задайте
NULL
, чтобы
getopt_long
вернула при обнаружении данной опции значение, заданное в
val
. В противном случае
getopt_long
возвращает 0 и записывает значение
val
в переменную, на которую указывает
flag
val
Значение
getopt_long
для данной опции, предназначенное для возврата
Для получения сведений о других опциях, связанных с расширениями функции
getopt
в проекте GNU и родственных функциях, см. страницы интерактивного справочного руководства к функции
getopt
.
Переменные окружения
Мы обсуждали переменные окружения в главе 2. Это переменные, которые могут использоваться для управления поведением сценариев командной оболочки и других программ. Вы также можете применять их для настройки пользовательской среды. Например, у каждого пользователя есть переменная окружения
HOME
, определяющая его исходный каталог, стандартное место старта его или ее сеанса. Как вы видели, просмотреть переменные окружения можно из строки приглашения командной оболочки:
$ echo $НOМЕ
/home/neil
Вы также можете воспользоваться командой оболочки
set
для получения списка всех переменных окружения.
В спецификации UNIX определено множество стандартных переменных окружения, применяемых для самых разных целей, включая тип терминала, имена редакторов, установленных по умолчанию, названия часовых поясов и т.д. Программа на языке С может получить доступ к переменным окружения с помощью функций
putenv
и
getenv
.
#include <stdlib.h>
char *getenv(const char *name);
int putenv(const char *string);
Окружение состоит из строк вида
имя=значение
. Функция
getenv
ищет в окружении строку с заданным именем и возвращает значение,
ассоциированное с этим именем. Она вернет
NULL
, если требуемая переменная не существует. Если переменная есть, но ее значение не задано, функция
getenv
завершится успешно и вернет пустую строку, в которой первый байт равен
NULL
. Строка, возвращаемая
getenv
, хранится в статической памяти, принадлежащей функции, поэтому для ее дальнейшего использования вы должны скопировать эту строку в другую, поскольку она может быть перезаписана при последующих вызовах функции
getenv
.
Функция
putenv
принимает строку вида
имя=значение
и добавляет ее в текущее окружение. Она даст сбой и вернет -1, если не сможет расширить окружение из-за нехватки свободной памяти. Когда это произойдет, переменной
errno
будет присвоено значение
ENOMEM
.
В упражнении 4.4 вы напишeте программу для вывода значения любой выбранной вами переменной окружения. У вас также будет возможность задать значение, если вы укажете второй аргумент программы.
Упражнение 4.4. Функции
getenv
и
putenv
1. Первые несколько строк после объявления функции
main
гарантируют корректный вызов программы environ.c с только одним или двумя аргументами:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *var, *value;
if (argc == 1 || argc > 3) {
fprintf(stderr, "usage: environ var [value]\n");
exit(1);
}
2. Сделав это, вы извлекаете значение переменной из окружения с помощью функции
getenv
:
var = argv[1];
value = getenv(var);
if (value)
printf("Variable %s has value %s\n", var, value);
else
printf("Variable %s has no value\n", var);
3. Далее проверьте, был ли при вызове программы указан второй параметр. Если был, вы задаете значение этого аргумента, конструируя строку вида