14.5.1. Utilizarea Subprocesului
Cea mai veche metodă de universalizare implică rularea shell-ului ca proces copil și instruirea acestuia de a universaliza numele fișierelor. Funcția standard popen () (vezi Capitolul 10) simplifică această metodă - executați comanda ls * .c cu popen () și citiți rezultatul. Această abordare poate părea oarecum simplistă, dar oferă încă o soluție portabilă la problema universalizării (de aceea, aplicații precum Perl utilizează aceasta).
Mai jos este un program care universalizează toate argumentele și afișează toate potrivirile.
3: #include
4: #include
14.5.2. Internalizarea universală
Dacă este necesară universalizarea mai multor nume de fișiere, rularea mai multor sub-shell-uri cu popen () va fi ineficientă. Funcția glob () vă permite să faceți universalizarea denumirilor de fișiere fără a rula subprocese, dar în detrimentul creșterii complexității și reducerii portabilității. Deși apelul către glob () este descris în standardul POSIX.2, multe variante Unix încă nu o acceptă.
int glob (const char * model, int steaguri,
int (* errfunc) (const char * epath, int eerrno), glob_t * pglob);
Primul parametru, model. Definește un șablon care trebuie să se potrivească cu numele fișierelor. Permite utilizarea operațiilor de universalizare *. și []. și, de asemenea, opțional
care sunt tratate în același mod ca în cochilii standard. Ultimul parametru indică structura, care este umplută cu rezultatele universalizării. Această structură este definită după cum urmează.
int gl_pathc; / * numărul de căi în gl_pathv * /
char ** gl_pathv; / * listă gl_pathc, corespunzătoare denumirilor căilor * /
int gl_offs; / * spațiul rezervat în gl_pathv pentru GLOB_DOOFFS * /
steagurile sunt una sau mai multe dintre următoarele valori, combinate cu un "OR" bitwise.
Returnează dacă apare o eroare (dacă funcția nu poate citi directorul directorului, de exemplu, din cauza unor probleme de acces).
Dacă șablonul se potrivește cu numele directorului, simbolul / va fi atașat la nume.
De obicei, numele căii de retur sunt sortate în ordine alfabetică. Dacă acest flag este setat, acestea nu sunt sortate.
La instalare, primele linii de pglob-> gl_offs din lista returnată a denumirilor de căi rămân goale. Aceasta vă permite să utilizați glob () în timpul alinierii unui număr de argumente care vor fi transmise direct la execv ().
Dacă niciunul dintre numele fișierelor nu se potrivește cu modelul, șablonul în sine este returnat ca singurul meci (de obicei, nu se întoarce un singur meci). În ambele cazuri, șablonul este returnat dacă nu conține operații de universalizare.
pglob ar trebui să fie rezultatul real al apelului anterior către glob (). și toate rezultatele acestui apel sunt adăugate la rezultatele apelului anterior. Acest lucru facilitează universalizarea mai multor șabloane.
De obicei, dacă operația de universalizare este precedată de caracterul \. este perceput ca un simbol obișnuit. De exemplu, modelul a \ * corespunde de obicei numai unui fișier numit *. Dacă este setat GLOB_NOESCAPE. simbolul \ își pierde semnificația specială, aa \ * se potrivește cu orice nume de fișier care începe cu un \. În acest caz, numele a \. și un \ bcd se va potrivi, dar arachnidul nu, pentru că nu conține \.
Cele mai multe shell-uri nu permit operații de universalizare pentru numele de fișiere care încep cu. (rulați ls * în directorul de acasă și comparați-l cu rezultatul ls-a.). Funcția glob () se comportă de obicei în acest fel, dar GLOB_PERIOD permite operațiilor de universalizare să funcționeze cu personajul principal. Valoarea GLOB_PERIOD în POSIX nu este definită.
Multe cochilii (urmând exemplul csh) desfăs, oară secvențe cu bretele curbate ca alternative; de exemplu, șablonul este extins la un b. și șablonul a - până la un ab ac. GLOB_BRACE face posibil acest comportament. Valoarea GLOB_BRACE în POSIX nu este definită.
Acționează ca GLOB_NOCHECK, cu excepția faptului că adaugă un șablon la lista de rezultate numai dacă nu conține caractere speciale. Valoarea GLOB_NOMAGIC în POSIX nu este definită.
Include o extensie cu un tilde în care
/ Extindeți la calea către directorul de domiciliu al utilizatorului curent și
utilizator - înainte de calea către utilizatorul utilizatorului de domiciliu de domiciliu. Valoarea GLOB_TILDE din POSIX nu este definită.
Se potrivește numai cu directoare, nu cu alte tipuri de fișiere. Valoarea GLOB_ONLYDIR în POSIX nu este definită.
Adesea glob () întâlnește directoare la care procesul nu are acces, ceea ce cauzează erori. Deși eroarea poate fi manipulată, cu toate acestea, dacă glob () returnează o eroare (GLOB_ERR), operația de universalizare nu poate fi repornit în cazul în care operațiunea de universalizare anterioară a întâmpinat o eroare. Deoarece este dificil să eliminați simultan erorile care apar în timpul execuției globului (). și pentru a finaliza universalizarea, glob () vă permite să transmiteți eroarea unei funcții speciale, care este definită în cel de-al treilea parametru glob ().
Prototipul acestei funcții este prezentat mai jos.
int globerr (const char * calename, int globerrno);
Funcția trece numele căii care a provocat eroarea și valoarea errno. returnat de unul dintre apelurile de sistem opendir (). readdir () sau stat (). Dacă funcția de eroare returnează o valoare mai mare decât zero, glob () este returnat cu o eroare. În caz contrar, operația de universalizare continuă.