Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
1213 if (argc < 3) {14 fprintf(stderr, "usage: %s path arg0 [ arg ... ]n", argv[0]);15 exit(1);16 }1718 path = argv[1];1920 execv(path, argv + 2); /* skip argv[0] and argv[1] */2122 fprintf(stderr, "%s: execv() failed: %sn", argv[0],23 strerror(errno));24 exit(1);25 }Первый аргумент является путем к запускаемой программе, а второй аргумент является новым именем для программы (которое большинство утилит игнорируют, кроме сообщений об ошибках); все остальные аргументы передаются вызываемой программе.
Строки 13–16 осуществляют проверку ошибок. Строка 18 сохраняет путь в
pathexec$ <b>ch09-run /bin/grep whoami foo</b> /* Запустить grep */<b>a line</b> /* Входная строка не подходит */<b>a line with foo in it</b> /* Входная строка подходит */<b>a line with foo in it</b> /* Это выводится */<b>^D</b> /* EOF */$ <b>ch09-run nonexistent-program foo bar</b> /* Демонстрация неудачи */ch09-run: execv() failed: No such file or directoryСледующий пример несколько неестественен: мы заставили
ch09-runfoo$ <b>ch09-run ./ch09-run foo</b>usage: foo path arg() [ arg ... ]Хотя она и не очень полезна,
ch09-runargv[0]В System III (примерно в 1980-м) команды
cplnmv/binargv[0]gmakegawkСегодня также дисковое пространство дешево; если из одного и того же исходного кода можно построить две почти идентичные программы, лучше это сделать, использовав
#ifdefgrepegrep9.1.4.4. Атрибуты, наследуемые
exec()Как и в случае с
fork()exec• Все открытые файлы и открытые каталоги; см. раздел 4.4.1 «Понятие о дескрипторах файлов» и раздел 3.3.1 «Базовое чтение каталогов». (Сюда не входят файлы, помеченные для закрытия при исполнении (close-on-exec), как описано далее в этой главе; см. раздел 9.4.3.1 «Флаг close-on-exec».)
• Установки umask; см. раздел 4.6 «Создание файлов».
• Текущий рабочий каталог, см. раздел 8.4.1 «Изменение каталога:
chdir()fchdir()• Корневой каталог; см. раздел 8.6 «Изменение корневого каталога:
chroot()• Текущее значение относительного приоритета.
• ID процесса и ID родительского процесса.
• ID группы процесса и контролирующий терминал; см. раздел 9.2.1 «Обзор управления работами».
• Маску сигналов процесса и любые ожидающие сигналы, а также любые не истекшие аварийные сигналы или таймеры (здесь не обсуждается; см. главу 10 «Сигналы»).
• Действительные ID пользователя и ID группы, а также дополнительный набор групп. Эффективные ID пользователя и группы (а следовательно, и сохраненные ID set-user и set-group) могут быть установлены с помощью битов setuid и setgid исполняемого файла. (Ничто из этого пока не обсуждалось; см. главу 11 «Права доступа и ID пользователя и группы».)
• Блокировки файлов сохраняются (также пока не обсуждалось; см. раздел 14.2 «Блокировка файлов»).
• Суммарное использованное время процессора для процесса и его потомков не меняется.
После
execfork()exec()После
execВ большинстве случаев при исполнении
forkexecforkexec9.1.5. Завершение процесса
Завершение процесса включает два шага: окончание процесса с передачей системе статуса завершения и восстановление информации родительским процессом.
9.1.5.1. Определение статуса завершения процесса
Статус завершения (exit status) (известный также под другими именами значения завершения (exit value), кода возврата (return code) и возвращаемого значения (return value)) представляет собой 8-битовое значение, которое родитель может использовать при завершении порожденного процесса (на языке Unix, «когда порожденный кончается (dies)»). По соглашению статус завершения 0 означает, что программа отработала без проблем. Любое ненулевое значение указывает на какую-нибудь разновидность ошибки; программа определяет используемые числа и их значения, если они есть. (Например,
grep$?