Linux программирование в примерах | страница 47
>182 while ((optc = getopt_long(argc, argv, "+iu:", longopts, NULL)) != -1)
>183 if (optc == 'u')
>184 putenv(optarg); /* Требуется GNU putenv. */
>185
>186 if (optind !=argc && !strcmp(argv[optind], "-")) /* Пропустить опции */
>187 ++optind;
>188
>189 while (optind < argc && strchr(argv[optind], '=')) /* Установить
> переменные окружения * /
>190 putenv(argv[optind++]);
>191
>192 /* Если программа не указана, напечатать переменные окружения и выйти. */
>193 if (optind == argc)
>194 {
>195 while (*environ)
>196 puts (*environ++);
>197 exit(EXIT_SUCCESS);
>198 }
Строки 174–179 переносят существующие переменные в новую копию окружения. В глобальную переменную >environ
помещается указатель на пустой локальный массив. Параметр >envp
поддерживает доступ к первоначальному окружению.
Строки 181–184 удаляют переменные окружения, указанные в опции >-u
. Программа осуществляет это, повторно сканируя командную строку и удаляя перечисленные там имена. Удаление переменных окружения основывается на обсуждавшейся ранее особенности GNU >putenv()
: при вызове с одним лишь именем переменной (без указанного значения) >putenv()
удаляет ее из окружения.
После опций в командной строке помещаются новые или замещающие переменные окружения. Строки 189–190 продолжают сканирование командной строки, отыскивая установки переменных окружения в виде '>имя=значение
'.
По достижении строки 192, если в командной строке ничего не осталось, предполагается, что >env
печатает новое окружение и выходит из программы. Она это и делает (строки 195–197).
Если остались аргументы, они представляют имя команды, которую нужно вызвать, и аргументы для передачи этой новой команде. Это делается с помощью системного вызова >execvp()
(строка 200), который замещает текущую программу новой. (Этот вызов обсуждается в разделе 9.1.4 «Запуск новой программы: семейство >exec()
»; пока не беспокойтесь о деталях.) Если этот вызов возвращается в текущую программу, он потерпел неудачу. В таком случае >env
выводит сообщение об ошибке и завершает программу.
>200 execvp(argv[optind], &argv[optind]);
>201
>202 {
>203 int exit_status = (errno == ENOENT ? 127 : 126);
>204 error(0, errno, "%s", argv[optind]);
>205 exit(exit_status);
>206 }
>207 }
Значения кода завершения >126
и >127
(определяемые в строке 203) соответствуют стандарту POSIX. >127
означает, что программа, которую >execvp()
попыталась запустить, не существует. (>ENOENT
означает, что файл не содержит записи в каталоге.)