Функції execxxx() призначені для запуску програми-нащадка з руйнуванням батька і через це не мають повертання в точку виклику. Нащадок займає всю пам’ять, руйнуючи батька. Існує декілька варіантів функцій execxxx():
1) для запуску програми-нащадка з отриманням середовища батька чи з визначенням для нащадка нового середовища;
2) для передачі нащадку параметрів в точку входу main() як масиву покажчиків чи як окремих покажчиків на слова у командному рядку;
3) з пошуком файлу що запускається тільки в поточному директорії чи з використанням для цього змінного середовища PATH.
Далі приводимо специфікацію функцій execxxx().
#include
<process.h>
int execl( char *path, char *arg0, …, char *argN, NULL );
int ex/ecle( char *path, char *arg0 ,…, char *argN, NULL, char **envp );
int execlp( char *path, char *arg0 ,…, char *argN, NULL );
int execlpe( char *path, char *arg0, …, char *argN, NULL, char **envp );
int execv( char *path,
char *argv[ ] );
int execve( char *path, char *argv[ ], char **envp );
int execvp( char *path, char *argv[ ] );
int execvpe( char *path, char *arg[ ], char
**envp );
Функції execxxx ()
запускають на виконання програму-нащадок, завантажувальний модуль якої
специфікується ASCIIZ-рядком, на початок якої вказує path. Існує декілька
модифікацій функцій, різниця між якими обговорюються далі по тексту.
Параметрами наведених функцій є:
char*path – покажчик на ASCIIZ – рядок специфікації файлу
завантажувального модуля програми-нащадка. Якщо не задається директорій та (чи)
накопичувач, пошук файлу виконується в поточних директорії та (чи)
накопичувачі. Якщо файл не знайдено, функції execl(), execle(), execv(),
execve() завершуються помилкою. Функції execlp(), execlpe(), execvp(),
execvpe() продовжують пошук файлу, що запускається, по маршрутах, які
перелічені у змінній середовища батька PATH. Розширення імені файлу може не
задаватися явно (.COM чи .EXE). При цьому спочатку буде відшукуватися файл з розширенням
.COM, а у випадку невдачі – з розширенням .EXE;
char *arg0, char *arg1,…, char *argN, NULL – покажчики на ASCIIZ-рядки,
які в сукупності утворюють командний рядок програми, яка запускається на
виконання (покажчики на окремі слова командного рядка). Для того щоб аргументи,
які передаються були доступними програмі-нащадку, точка входу в нього повинна
описуватися так:
якщо нащадку не потрібен доступ до рядків середовища,
int main( int argc, char
**argv )
якщо нащадку необхідний доступ до рядків середовища,
int main( int argc, char
**argv, char**envp )
NULL – покажчик, значення якого = 0. Він використовується як обмежувач
у масиві покажчиків char argv[ ]. Значення першого слова командного рядка
завжди, за згодами Сі, являє собою специфікацію файлу який запущений на
виконання. Через це рядок, на який вказує arg0, повинен містити ім’я файлу який
вже запущено. На відміну від path arg0 не використовується для пошуку файлу
програми який запускається на виконання і може не містити повну специфікацію
файлу який запускається.
char **argv – покажчик на масив, кожний елемент якого є покажчиком на
окреме слово командного рядка. Масив завершується покажчиком NULL. Параметр
використовується функціями execv(), execve(), execvp (), execvpe () в тих
випадках, коли окремі покажчики char *arg0, char *arg1, …, char *argN, NULL
зібрані в масив покажчиків.
char **envp – покажчик на масив, кожний елемент якого є покажчиком на
рядок середовища нащадка. Масив завершується покажчиком NULL. Параметр
використовується функціями execle(), execlpe(), execvе(), execvpe(), тобто в
тих випадках, коли при запуску нової програми необхідно перевизначити
середовище нащадка. В усіх інших функціях execxxx() середовище повністю
копіюється чи, як кажуть, нащадується від батька;
Якщо запуск програми на виконання пройшов успішно, функції execxxx() не
повертають керування у точку виклику. У випадку невдачі повертається –1 і код
помилки записується у зовнішній змінній
errno. Можливі значення для кодів помилок наведені нижче. (Табл. 13).
Табл. 13. Коди помилок, які
повертаються
функціями execxxx() та spawnxxx()
Константа |
Причина помилки |
E2BIG |
Загальна довжина всіх слів командного рядка,
включаючи пробіли, перевищує 128 байт, або загальний об’єм рядків середовища
перевищує 32К байт |
EMFILE |
Не відкритий
файл завантажувального модуля, так як досягнута межа на число
одночасно відкритих файлів |
ENOENT |
Не знайдено файл завантажувального модуля |
ENOEXEC |
Файл, що запускається на виконання не є .COM
чи .EXE-файлом, або .EXE-файл ушкоджено на диску |
ENOMEM |
Помилка при виділенні оперативної пам’яті
нащадку |
Далі будуть наведені приклади програм, які запускають на виконання різноманітними способами програму-нащадка. Нащадок – це тестова програма, яка виводить на екран отриманий в точці входу main() командний рядкяк і середовище програми. Завантажувальний модуль нащадка отримано компіляцією програми L5_2.C:
/* L5_2.C */
#include <stdio.h>
main( int argc, char **argv, char **envp ) {
char *ptr = argv[ 0 ];
printf( “Аргументи командного рядка,
які передані”\
”програмі%s\n”, argv[ 0 ] );
while( argc-- ) puts( *argv++ );
printf( “Середовище програми%s\n”, ptr
);
while( *envp ) puts( *envp++);
}
Наведемо приклади програм, які використовують різні варіанти функції execxxx(). Наступна програма L5_3.C, використовуючи функцію execv(), запускає на виконання програму, ім’я файлу якої задано першим аргументом командного рядка:
/* L5_3.C */
#include <stdio.h>
#include <process.h>
main(int argc, char**argv) {
if( argc == 1 ) { /* чи всі параметри задані? */
printf( “Використання програми:”\
”%s
Ім’я_файлу_нащадка[параметри]\n”, argv[ 0 ] );
return( 255 );
}
printf( “Запуск на виконання%s через
execv()\n”, argv[ 1 ] );
argv++;
if( execv( argv[0], argv) == -1 ) {
printf( “\aНевдача при запуску
програми %s\n”,argv[0]);
perror( “Причина” );
return( 254 );
}
return( 0 );
}
![]() |
![]() |
![]() |