Выбрать главу

/* Устанавливает соответствующее VALUE для каждого NAME и запускает COMMAND */

-i, --ignore-environment /* запустить с пустым окружением */

-u, --unset=NAME         /* удалить переменную из окружения */

--help                   /* показать этот экран справки и выйти */

--version                /* вывести информацию о версии и выйти */

/* Простое - предполагает -1. Если не указана COMMAND, отображает

   имеющееся окружение.

Об ошибках сообщайте в <bug-coreutils@gnu.org>. */

Вот несколько примеров вызовов команды:

$ env - myprog arg1 /* Очистить окружение, запустить программу с args */

$ env - РАТН=/bin:/usr/bin myprog arg1 /* Очистить окружение, добавить PATH, запустить программу */

$ env -u IFS PATH=/bin:/usr/bin myprog arg1 /* Сбросить IFS, добавить PATH, запустить программу */

Код начинается со стандартной формулировки авторских прав GNU и разъясняющего комментария. Мы для краткости их опустили. (Формулировка авторского права обсуждается в Приложении С «Общедоступная лицензия GNU». Показанного ранее вывода --help достаточно для понимания того, как работает программа.) За объявленным авторским правом и комментарием следуют подключаемые заголовочные файлы и объявления. Вызов макроса 'N_("string")' (строка 93) предназначен для использования при локализации программного обеспечения, тема, освещенная в главе 13 «Интернационализация и локализация». Пока вы можете рассматривать его, как содержащий строковую константу.

80  #include <config.h>

81  #include <stdio.h>

82  #include <getopt.h>

83  #include <sys/types.h>

84  #include <getopt.h>

85

86  #include "system.h"

87  #include "error.h"

88  #include "closeout.h"

89

90  /* Официальное имя этой программы (напр., нет префикса 'g'). */

91  #define PROGRAM_NAME "env"

92

93  #define AUTHORS N_ ("Richard Mlynarik and David MacKenzie")

94

95  int putenv();

96

97  extern char **environ;

98

99  /* Имя, посредством которого эта программа была запущена. */

100 char *program_name;

101

102 static struct option const longopts[] =

103  {

104  {"ignore-environment", no_argument, NULL, 'i'},

105  {"unset", required_argument, NULL, 'u'},

106  {GETOPT_HELP_OPTION_DECL},

107  {GETOPT_VERSION_OPTION_DECL},

108  {NULL, 0, NULL, 0}

109 };

GNU Coreutils содержит большое число программ, многие из которых выполняют одни и те же общие задачи (например, анализ аргументов). Для облегчения сопровождения многие типичные идиомы были определены в виде макросов. Двумя таким макросами являются GETOPT_HELP_OPTION_DECL и GETOPT_VERSION_OPTION (строки 106 и 107). Вскоре мы рассмотрим их определения. Первая функция, usage(), выводит информацию об использовании и завершает программу. Макрос _("string") (строка 115, используется также по всей программе) также предназначен для локализации, пока также считайте его содержащим строковую константу.

111 void

112 usage(int status)

113 {

114  if (status '= 0)

115   fprintf(stderr, _("Try '%s --help' for more information.\n"),

116    program_name);

117  else

118  {

119   printf (_("\

120    Usage: %s [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]\n"),

121    program_name);

122   fputs (_("\

123    Set each NAME to VALUE in the environment and run COMMAND. \n\

124    \n\

125    -i, --ignore-environment start with an empty environment\n\

126    -u, --unset=NAME remove variable from the environment\n\

127    "), stdout);

128   fputs(HELP_OPTION_DESCRIPTION, stdout);

129   fputs(VERSION_OPTION_DESCRIPTION, stdout);

130   fputs(_("\

131    \n\

132    A mere - implies -i. If no COMMAND, print the resulting\

133    environment.\n"), stdout);

134   printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);

135  }

136  exit(status);

137 }

Первая часть main() объявляет переменные и настраивает локализацию. Функции setlocale(), bindtextdomain() и textdomain() (строки 147–149) обсуждаются в главе 13 «Интернационализация и локализация». Отметим, что эта программа использует аргумент main() envp (строка 140). Это единственная программа Coreutils, которая так делает. Наконец, вызов atexit() в строке 151 (см. раздел 9.1.5.3. «Функции завершения») регистрирует библиотечную функцию Coreutils, которая очищает все выходные буферы и закрывает stdout, выдавая сообщение при ошибке. Следующая часть программы обрабатывает аргументы командной строки, используя getopt_long().

139 int

140 main(register int argc, register char **argv, char **envp)

141 {

142  char *dummy_environ[1];

143  int optc;

144  int ignore_environment = 0;

145

146  program_name = argv[0];

147  setlocale(LC_ALL, "");

148  bindtextdomain(PACKAGE, LOCALEDIR);

149  textdomain(PACKAGE);

150

151  atexit(close_stdout);

152

153  while ((optc = getopt_long(argc, argv, "+iu:", longopts, NULL)) != -1)

154  {

155   switch (optc)

156   {

157   case 0:

158    break;

159   case 'i':

160    ignore_environment = 1;

161    break;

162   case 'u':

163    break;

164   case_GETOPT_HELP_CHAR;

165   case_GETOPT_VERSION_CHAR(PROGRAM_NAME, AUTHORS);

166   default:

167    usage(2);

168   }

169  }

170

171  if (optind != argc && !strcmp(argv[optind], "-"))

172   ignore_environment = 1;

Вот отрывок из файла src/sys2.h в дистрибутиве Coreutils с упомянутыми ранее определениями и макросом 'case_GETOPT_xxx', использованным выше (строки 164–165):

/* Вынесение за скобки общей части кода, обрабатывающего --help и