Майкл Джонсон, Ерік троан - розробка додатків в середовищі linux

14.5.1. Використання подпроцесса

Найстаріший метод універсалізації передбачає запуск оболонки в якості дочірнього процесу і вказівка ​​їй універсалізуватися файлові імена. Стандартна функція popen () (див. Розділ 10) спрощує цей метод - просто запустіть команду ls * .с за допомогою popen () і прочитайте результат. Цей підхід може здатися дещо спрощеним, але все ж він забезпечує переноситься рішення проблеми універсалізації (ось чому програми на кшталт Perl використовують його).

Нижче наведена програма, яка універсалізує всі аргументи і відображає всі збіги.

3: #include

4: #include

14.5.2. Внутрішня універсалізація

Якщо необхідно універсалізуватися кілька файлових імен, запуск декількох подоболочек за допомогою popen () буде неефективним. Функція glob () дозволяє універсалізувати імена файлів без запуску будь-яких подпроцессов, однак за рахунок збільшення складності і зниження переносимості. Незважаючи на те що виклик glob () описаний в стандарті POSIX.2, багато варіанти Unix досі його не підтримують.

int glob (const char * pattern, int flags,

int (* errfunc) (const char * epath, int eerrno), glob_t * pglob);

Перший параметр, pattern. визначає шаблон, якому повинні відповідати імена файлів. У ньому допускається застосування операцій універсалізації *. і []. а також необов'язково і

які трактуються так само, як в стандартних оболонках. Останній параметр вказує на структуру, яка заповнюється результатами універсалізації. Ця структура визначена наступним чином.

int gl_pathc; / * Кількість шляхів в gl_pathv * /

char ** gl_pathv; / * Список gl_pathc, відповідних іменам шляхів * /

int gl_offs; / * Простір, зарезервоване в gl_pathv для GLOB_DOOFFS * /

flags - це одне або кілька перерахованих нижче значень, об'єднаних за допомогою бітового "АБО".

Повертається в разі помилки (якщо функція не може прочитати зміст каталогу, наприклад, через проблеми з доступом).

Якщо шаблон відповідає імені каталогу, при поверненні до цього імені буде доданий символ /.

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

При установці перші рядки pglob-> gl_offs в повернутому списку імен шляхів залишаються порожніми. Це дозволяє використовувати glob () під час вибудовування ряду аргументів, які будуть передані прямо в execv ().

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

pglob імовірно є дійсним результатом попереднього виклику glob (). і будь-які результати цього виклику додаються до результатів попереднього виклику. Це полегшує універсалізацію безлічі шаблонів.

Зазвичай якщо операції універсалізації передує символ \. вона сприймається як звичайний символ. Наприклад, шаблон а \ * зазвичай відповідає тільки файлу по імені а *. Якщо встановлюється GLOB_NOESCAPE. символ \ втрачає своє особливе значення, aa \ * відповідає будь-якому імені файлу, що починається з символів а \. В такому випадку імена а \. і a \ bcd будуть відповідати, але arachnid - немає, оскільки воно не містить \.

Більшість оболонок не дозволяють застосовувати операції універсалізації для файлових імен, що починаються з. (Запустіть ls * в своєму домашньому каталозі і порівняйте отримане з результатом ls - а.). Функція glob () зазвичай поводиться подібним чином, але GLOB_PERIOD дозволяє операціям універсалізації працювати з провідним символом. Значення GLOB_PERIOD в POSIX не визначене.

Багато оболонки (наслідуючи приклад csh) розгортають послідовності з фігурними дужками як альтернативи; наприклад, шаблон розгортається до a b. а шаблон a - до a ab ас. GLOB_BRACE уможливлює таку поведінку. Значення GLOB_BRACE в POSIX не визначене.

Діє подібно GLOB_NOCHECK за винятком того, що він додає шаблон до списку результатів тільки в тому випадку, якщо вона не містить спеціальних знаків. Значення GLOB_NOMAGIC в POSIX не визначене.

Включає розширення з тильдой, в якому

/ Розгортаються до шляху до домашнього каталогу поточного користувача, а

user - до шляху до домашнього каталогу користувача user. Значення GLOB_TILDE в POSIX не визначене.

Збігається тільки з каталогами, а не з іншими типами файлів. Значення GLOB_ONLYDIR в POSIX не визначене.

Часто glob () наштовхується на каталоги, до яких у процесу немає доступу, що викликає помилки. Хоча помилку можна якимось чином обробити, однак якщо glob () повертає помилку (GLOB_ERR), операцію універсалізації не можна перезапустити там, де попередня операція універсалізації зіткнулася з помилкою. Оскільки складно одночасно усувати помилки, що відбуваються під час виконання glob (). і завершувати універсалізацію, glob () дозволяє передати помилку в спеціально передбачену для цього функцію, яка визначається в третьому параметрі glob ().

Прототип цієї функції показаний нижче.

int globerr (const char * pathname, int globerrno);

Функції передається колійне ім'я, що викликало помилку, і значення errno. повернене одним із системних викликів opendir (). readdir () або stat (). Якщо функція помилки повертає величину більше нуля, glob () повертається з помилкою. В іншому випадку операція універсалізації триває.

Схожі статті