Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lek_4,5_.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
412.16 Кб
Скачать

2. Використання системних функцій

2.1. Системна функція fork ()

Системна функція (або системний виклик) fork () створює новий процес, який є дублікатом процесу який його викликав, тобто його батька. При успіш­ному виконанні функція fork () повертає батьківському і дочірньому процесам два різних значення. Дочірньому процесу число 0, а батьківському – значення PID дочірнього процесу. Батьківський і дочірній процеси продовжують викону­ватися з інструкції, безпосередньо наступній за функцією fork (). У випадку невдалого виконання (це коли дочірній процес не був створений) батьківському процесу повертається число -1.

Синопсис

# include <unistd>

pid_t fork (void);

Невдале виконання функції fork () можливе у випадку, коли система не володіє ресурсами для створення ще одного процесу. Це відбувається при пере­вищенні обмежень (якщо вони існують) на кількість дочірніх процесів, які мо­же породжувати батько, або на кількість процесів, які виконуються в межах всієї системи. В цьому випадку встановлюється змінна error, яка означає наяв­ність помилки.

2.2. Системні функції exec

Сімейство функцій exec призначене для заміни образу процесу, який йо­го викликає, образом нового процесу. При виклику функції fork () створює­ть­ся новий процес, який точною копією батьківського процесу, а функція exec () замінює образ скопійованого процесу образом копії. Образ нового процесу є звичайний виконуваний файл, який миттєво завантажується на виконання. Цей файл можемо задати за допомогою імені і шляху доступу до нього. Функції сі­мейства exec можуть передавати новому процесу аргументи командної стрічки, а також встановити змінні середовища. Якщо функція виконалася успішно, во­на не повертає ніякого значення, оскільки образ процесу, який містить звертан­ня до функції exec, вже пере записано. У випадку невдачі процесу, який вик­ли­кає, повертається число -1. Всі функції exec () можуть мати невдале закінчення при наступних умовах:

  • дозволи не визнано;

дозвіл на пошук відкидається для каталогу файлів, що виконуються;

дозвіл на виконання відкидається для файлу, який виконується;

  • файли не існують;

файл, який виконується не існує;

каталог не існує;

  • файл неможливо виконати;

файл неможливо виконати, оскільки він відкритий для запису іншим процесом;

файл не є виконуваним;

  • проблеми з символічними посиланнями;

при аналізі шляху до файлу, що виконується, символічні посилання створюють цикл;

символічні посилання роблять шлях до файлу, який виконується, надто довгим.

Функції сімейства exec використовуються разом з функцією fork (). Фун­кція fork () створює та ініціює дочірній процес за образом і подібністю бать­кі­вського. Образ дочірнього процесу в подальшому замінює образ свого предка за допомогою виклику функції exec (). Приклад використання функцій fork () і exec () показано в лістінгу 1.

 Лістінг 1. Використання системних функцій fork () і exec ()

 . . .

RtValue = fork ();

if (RtValue = = 0) {

execl (/path/direct, direct,  . );

}

В лістінгу 1 показано виклик функції fork (). Значення, які вона повер­тає, зберігається у змінній RtValue. Якщо значення RtValue рівне 0, отже, це – дочірній процес, і в ньому викликається функція execl () з параметрами. Пер­ший параметр містить шлях до модуля, який виконується, другий – інструкцію, для виконання, третій – аргумент. Другий параметр, direct, являє собою ім'я утиліти, яка перераховує всі каталоги і підкаталоги з даного каталогу. Всього існує шість версій функції exec, передбачених для використання різних угод про виклики.

2.3. Функції execl ()

Функції execl (),execle () і execlp () передають функції командної стрічки у вигляді списку. Кількість аргументів командної стрічки повинна бути відома під час компіляції.

  • int execl (const char *path, const char *arg0, . . ./*, (char *)0 */);

Тут path – дорожнє (шляхове) ім'я програми, яка виконується. Його мо­жна подати у вигляді повного складеного імені або відносного складеного імені з біжучого каталогу. Наступні параметри є списком аргументів командної стрі­ч­ки, від arg0 до argn. Всього може бути n аргументів. Даний список завер­шу­є­ть­ся NULL-вказівником.

  • int execle (const char *path, const char *arg0, . . ./*, (char *)0 *, char * const envp[]*/);

Дана функція аналогічна функції execl () з однією відмінністю: вона має додатковий параметр, envp[]. Цей параметр вказує на нове середовище для нового процесу, тобто envp[] – це вказівник на стрічковий масив з завершаль­ним нульовим символом. Кожна його стрічка, також завершується нульовим символом, має наступну форму

name = value

Тут name – ім'я змінної середовища, а value – стрічка що зберігається. Значення параметру envp[] можемо присвоїти наступним чином:

char *const envp[]={“PATH=/opt/kde2:/sbin”, “HOME = /home”, NULL};

Тут PATH і HOME – змінні середовища.

  • int execlp (const char *fale, const char *arg0, . . ./*, (char *)0 */);

Тут fale – ім'я програми, яка виконується. Для визначення місця знахо­дження програм, що виконуються, використовується змінна середовища PATH. Останні параметри є списком аргументів командної стрічки (дивись опис фун­кції execl ()).

Приклад застосування синтаксису функції execl () зрізними аргумента­ми:

char *const args[] = {“direct”, “.”, NULL};

char *const envp[] = {“fales=50”, NULL};

execl (“path/direct”, “direct”, “.”,NULL);

execle (“path/direct”, “direct”, “.”,NULL, envp);

execlp (“direct”, “direct”, “.”,NULL);

Тут в кожному прикладі виклику execl-функції активізований процес викликає програму direct.

Синопсис

# include <unistd.h

int execl (const char *path, const char *arg0, . . ./*, (char *)0 */);

int execle (const char *path, const char *arg0, . . ./*, (char *)0 *, char * const envp[]*/);

int execlp (const char *fale, const char *arg0, . . ./*, (char *)0 */);

int execv (const char *path, char *const arg[]);

int execve (const char *path, char *const arg[], char *const envp[]);

int execvp (const char *fale, char *const arg[]);

2.4. Функція execv ()

Функції execv (),execve () і execvp () передають аргументи командної стрічки у вектори вказівників на стрічки із завершальним нульовим символом. Кількість аргументів командної стрічки повинно бути відоме під час компіляції. Елемент argv [0] як правило є командою.

  • int execv (const char *path, char *const arg[]);

Тут path –дорожнє (шляхове) ім'я програми, що виконується. Його мо­жемо задати у вигляді повного складеного імені або відносного складе­ного імені з біжучого каталогу. Наступний параметр є вектором (з заве­ршальним нульовим символом), який містить аргументи командної стрічки, подані у вигляді стрічок з завершальним нульовим символом. Всього може бути n аргументів. Даний вектор завершується NULL-вка­зівником. Елементу arg[] можемо надати значення наступним чином:

char *const arg[] = {“traverse”, “.”, “>”, “1000”, NULL};

Приклад виклику цієї функції:

execv (“traverse”, arg);

В цьому випадку утиліта traverse перерахує всі файли в біжучому ката­лозі розмір яких більше 1000 байт.

  • int execve (const char *path, char *const arg[], char *const envp[]);

Дана функція аналогічна функції execv (), за однією відмінністю: вона має додатковий параметр, envp[], який описано вище.

  • int execvp (const char *fale, char *const arg[]);

Тут fale – ім'я програми яка виконується. Наступний параметр є векто­ром (з завершальним нульовим символом), який містить аргументи ко­мандної стрічки, подані у вигляді стрічок з завершальними нульовими символами. Всього може бути n аргументів. Даний вектор завершує­ть­ся NULL-вка­зівником.

Подано приклад застосування синтаксису функції execvp () з різними аргументами:

char *const arg [ ] = {“traverse”, “.”, “>”, “1000”, NULL};

char *const evenp [ ] = {“files = 50”, NULL};

execv (“/path/traverse”, arg};

execve (“/path/traverse”, arg, envp};

execv (“traverse”, arg};

Тут в кожному прикладі виклику execv-функції активізований процес виконує програму traverse.

2.5. Визначення обмежень для функції exec ()

Існують обмеження на розміри вектора argv [ ] і масиву envp [ ], які пе­ре­даються функціям сімейства exec. Для визначення максимального розміру аргументів командної стрічки і розміру змінних середовища при використанні exec-функцій (які приймають параметр envp [ ] можемо використати функцію sysconf ()). Щоб дана функція повернула розмір, її параметру name необхідно передати значення _SC_ARG_MAX.

Синопсис

# include < unistd.h >

long sysconf (int name);

Ще одним обмеженням при використанні функцій сімейства exec та інших функцій, які застосовуються для створення процесів, є максимальна кількість процесів, що виконуються одночасно, яке доступне для одного користувача. Щоб функція sysconf () повернула дане число, її параметру name необхідно передати значення _SC_CHILD_MAX.

2.6. Читання та встановлення змінних середовища

Змінні середовища, це стрічки з нульовими символами в кінці, в яких зберігається наступна системна інформація: шляхи до каталогів, які містять ко­манди, бібліотеки, функції і процедури які використовує процес. Їх можна та­кож використовувати для передачі довільних визначених користувачем даних між батьківським і дочірнім процесами. Вони забезпечують механізм надання процесу спеціальної інформації без необхідності жорсткої її сполучення з ко­дом програми. Змінні середовища визначені системою і спільно використову­ю­ться всіма її оболонками та процесами. Ці змінні ініціюються файлами запуску. Частіше всього використовуються наступні системні змінні.

$HOME

Повне складене ім'я користувача

$PATH

Список каталогів для файлів, що виконуються при виконанні команд

$MAIL

Повне складене ім'я поштового ящика користувача

$USER

Ідентифікатор (id) користувача

$SHELL

Повне складене ім'я командної оболонки зареєстрованого користувача

$TERM

Тип терміналу користувача

Змінні середовища можуть зберігатися у файлі або у списку, які нале­жа­ть середовищу. Даний список середовища містить вказівники на стрічки з ну­льо­вими символами в кінці. Коли процес починає виконання, змінна

extern char **environ

буде вказувати на список середовища. Стрічки які складають список середо­ви­ща, мають наступний формат:

name = value

Процеси ініційовані за допомогою функцій execl (),execlp (),execv () і execvp (), успадковують конфігурацію середовища батьківського процесу. Про­цеси, ініційовані за допомогою функцій execve () і execle (), самі встановлюють середовище.

Існують функції та утиліти, які дозволяють опитати, добавити або моди­фікувати змінні середовища. Функція getevn ()використовується для визначення факту встановлення заданої змінної. Змінна, яка вас цікавить задається за допо­могою параметру name. Якщо задана змінна не встановлена, функція повертає значення NULL. В інакшому випадку (якщо змінна встановлена), функція пове­ртає вказівник на стрічку, яка містить її значення.

Синопсис

# include < stdlib.h >

char *getenv ( const char *name );

int setenv (const char *name, const char *value, int overwrite );

void unsetenv ( const char *name );

Розглянемо приклад:

string Path;

Path = getenv (“PATH”);

Тут стрічці Path присвоюється значення, яке міститься у вбудованій змінній PATH.

Функція setenv () використовується для зміни значення існуючої змінної середовища або добавлення нової змінної в середовище процесу, який викли­кає. Параметр name містить ім'я змінної середовища, яку необхідно добавити або змінити. Заданій змінній присвоюється значення, яке передається через па­раметр value. Якщо змінна, задана параметром name, вже існує, її попереднє значення замінюється значенням, заданим параметром value при умові, якщо параметр overwrite містить ненульове значення. Якщо ж overwrite рівне 0, вміст змінної середовища модифікується. Функція setenv () повертає 0 при повертає значення 0 при вдалому виконанні, в інакшому випадку – значення -1. Функція unsetenv () видаляє змінну середовища, яка була задана параметром name.

2.7. Використання функції system () для породження процесів

Функція system () використовується для виконання команд або запуску програми. Функція system () виконують функцію fork (), а потім дочірній про­цес викликає функцію exec () з оболонкою, виконуючи задану команду або про­граму.

Синопсис

# include < stdlib.h >

int system (const char *string);

В якості параметру string можемо передати системну команду або ім'я файлу, який виконується. При вдалому виконанні функція повертає статус заве­ршення команди або значення, яке повертається програмою (якщо таке перед­ба­чено). Помилки можуть виникати на декількох рівнях, тобто помилка може відбутися при виконанні функції fork () або exec () чи задана оболонка може бути невідповідною для виконання команди або програми.

Функція system () повертає значення батьківському процесу. При невда­лому виконанні функція exec () повертає число 127, а при виявленні інших по­милок – число -1. Ця функція не впливає на стан очікування дочірніх процесів.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]