Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

#include <stdlib.h>

int main {

 int return_value;

 return_value = system("ls -l /");

 return return_value;

}

Функция

system
возвращает код завершения указанной команды. Если интерпретатор не может быть запущен, возвращается значение 127, а в случае возникновения других ошибок — -1.

Поскольку функция

system
запускает интерпретатор команд, она подвержена всем тем ограничениям безопасности, что и системный интерпретатор. Рассчитывать на наличие какой-то конкретной версии Bourne shell не приходится. В большинстве UNIX-систем программа
/bin/sh
представляет собой символическую ссылку на другой интерпретатор. В Linux — это
bash
(Bourne-Again SHell), причем в разных дистрибутивах присутствуют разные его версии. Вызов из функции
system
программы с привилегиями пользователя
root
также может иметь неодинаковые последствия в разных системах. Таким образом, лучше создавать процессы с помощью функций
fork
и
exec
.

3.2.2. Функции fork и exec

В DOS и Windows API имеется семейство функций

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

Вызов функции fork

Вызывая функцию

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

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

getpid
и узнать, где именно она находится. Но сама функция
fork
реализует другой способ: она возвращает разные значения в родительском и дочернем процессах. Родительский процесс получает идентификатор своего потомка, а дочернему процессу возвращается 0. В системе нет процессов с нулевым идентификатором, так что программа легко разбирается в ситуации.

В листинге 3.3 приведен пример ветвления программы с помощью функции

fork
. Учтите, что первая часть инструкции
if
выполняется только в родительском процессе, тогда как ветвь
else
— только в дочернем.

Листинг 3.3. (fork.c) Ветвление программы с помощью функции
fork

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

int main {

 pid_t child_pid;

 printf("The main program process ID is %d\n",

(int)getpid);

 child_pid = fork;

 if (child_pid != 0) {

printf("This is the parent process, with ID %d\n",

(int)getpid);

printf("The child's process ID is %d\n", (int)child_pid);

 } else

printf("This is the child process, with ID %d\n",

(int)getpid);

 return 0;

}

Семейство функций exec

Функции семейства

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

Функции, входящие в семейство

exec
, немного отличаются друг от друга по своим возможностям и способу вызова.

■ Функции, в названии которых присутствует суффикс

'p'
(
execvp
и
execlp
), принимают в качестве аргумента имя программы и ищут эту программу в каталогах, определяемых переменном среды
PATH
. Всем остальным функциям нужно передавать полное путевое имя программы.

■ Функции, в названии которых присутствует суффикс

'v'
(
execv
,
execvp
и
execve
), принимают список аргументов программы в виде массива строковых указателей, оканчивающегося
NULL
– указателем. Функции с суффиксом
'l'
(
execl
,
execlp
и
execle
) принимают список аргументов переменного размера.

■ Функции, в названии которых присутствует суффикс

'e'
(
execve
и
execle
), в качестве дополнительного аргумента принимают массив переменных среды. Этот массив содержит строковые указатели и оканчивается пустым указателем. Каждая строка должна иметь вид
"ПЕРЕМЕННАЯ=значение"
.

Поскольку функция

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

Список аргументов, передаваемых программе, аналогичен аргументам командной строки, указываемым при запуске программы в интерактивном режиме. Их тоже можно получить с помощью параметров

argc
и
argv
функции
main
. Не забывайте, когда программу запускает интерпретатор команд, первый элемент массива argv будет содержать имя программы, а далее будут находиться переданные программе аргументы. Аналогичным образом следует поступить, формируя список аргументов для функции
exec
.

Совместное использование функций fork и exec

Стандартная методика запуска одной программы из другой такова: сначала с помощью функции

fork
создается дочерний процесс, затем в нем вызывается функция
exec
. Это позволяет главной программе продолжать выполнение в родительском процессе.

Программа, показанная в листинге 3.4, отображает содержимое корневого каталога с помощью команды

ls
, как и программа в листинге 3.2. Но на этот раз команда
ls
вызывается не из интерпретатора, а напрямую; ей передаются аргументы
– l
и
/
.

Поделиться:
Популярные книги

Кадет Морозов

Шелег Дмитрий Витальевич
4. Живой лёд
Фантастика:
боевая фантастика
5.72
рейтинг книги
Кадет Морозов

Царь царей

Билик Дмитрий Александрович
9. Бедовый
Фантастика:
фэнтези
мистика
5.00
рейтинг книги
Царь царей

Вернуть невесту. Ловушка для попаданки 2

Ардова Алиса
2. Вернуть невесту
Любовные романы:
любовно-фантастические романы
7.88
рейтинг книги
Вернуть невесту. Ловушка для попаданки 2

S-T-I-K-S. Пройти через туман

Елисеев Алексей Станиславович
Вселенная S-T-I-K-S
Фантастика:
боевая фантастика
7.00
рейтинг книги
S-T-I-K-S. Пройти через туман

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Монстр из прошлого тысячелетия

Кодекс Крови. Книга ХII

Борзых М.
12. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Крови. Книга ХII

Автобиография

Твен Марк
Документальная литература:
биографии и мемуары
6.25
рейтинг книги
Автобиография

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Воин-Врач

Дмитриев Олег
1. Воин-Врач
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
6.00
рейтинг книги
Воин-Врач

Хроники Тириса. Книга 3

Маханенко Василий Михайлович
3. Хроники Тириса
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
5.00
рейтинг книги
Хроники Тириса. Книга 3

Запечатанный во тьме. Том 2

NikL
2. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 2

Эволюционер из трущоб

Панарин Антон
1. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Газлайтер. Том 1

Володин Григорий
1. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 1