system(3)

NUME
sistem - execută o comandă shell

BIBLIOTECA
Biblioteca C standard (libc, -lc)

SINOPSIS
#include <stdlib.h>

int system(const char *comandă);

DESCRIERE
Funcția de bibliotecă system() se comportă ca și cum ar fi utilizat fork(2) pentru a crea un proces-copil care să execute comanda shell specificată în comandă utilizând execl(3) după cum urmează:

    execl("/bin/sh", "sh", "-c", comandă, (char *) NULL);

system() returnează după ce comanda a fost finalizată.

În timpul executării comenzii, SIGCHLD va fi blocat, iar SIGINT și SIGQUIT vor fi ignorate, în procesul care apelează system(); (aceste semnale vor fi tratate în conformitate cu valorile lor implicite în interiorul procesului-copil care execută comanda).

Dacă comandă este NULL, atunci system() returnează o stare care indică dacă un shell este disponibil pe sistem.

VALOAREA RETURNATĂ
Valoarea returnată de system() este una dintre următoarele:

•   Dacă comandă este NULL, atunci o valoare diferită de zero dacă este disponibil un shell, sau 0 dacă nu este disponibil niciun shell.

•   Dacă un proces-copil nu a putut fi creat sau starea acestuia nu a putut fi recuperată, valoarea de returnare este -1 și errno este configurată pentru a indica eroarea.

•   În cazul în care un shell nu a putut fi executat în procesul-copil, atunci valoarea de returnare este ca și cum shell-ul copil s-ar fi încheiat prin apelarea _exit(2) cu starea 127.

•   Dacă toate apelurile sistemului reușesc, atunci valoarea de returnare este starea de terminare a shell-ului copil utilizat pentru a executa comandă; (starea de terminare a unui shell este starea de terminare a ultimei comenzi pe care o execută).

În ultimele două cazuri, valoarea de returnare este o „stare de așteptare” care poate fi examinată utilizând macrocomenzile descrise în waitpid(2); (și anume, WIFEXITED(), WEXITSTATUS() și așa mai departe).

system() nu afectează starea de așteptare a niciunui alt copil.

ERORI-IEȘIRE
system() poate eșua cu oricare dintre aceleași erori ca fork(2).

ATRIBUTE
Pentru o explicație a termenilor folosiți în această secțiune, a se vedea attributes(7).
Interfață | Atribut | Valoare
system() | Siguranța firelor | MT-Safe

STANDARDE
C11, POSIX.1-2008.

ISTORIC
POSIX.1-2001, C89.

NOTE
system() oferă simplitate și confort: se ocupă de toate detaliile apelurilor fork(2), execl(3) și waitpid(2), precum și de manipulările necesare ale semnalelor; în plus, shell-ul efectuează substituțiile obișnuite și redirecționările de In/Ieș pentru comandă. Principalul cost al system() este ineficiența: sunt necesare apeluri de sistem suplimentare pentru a crea procesul care rulează shell-ul și pentru a executa shell-ul.

Dacă macrocomanda de testare a caracteristicii _XOPEN_SOURCE este definită (înainte de includerea fișierelor de antet any), atunci macrocomenzile descrise în waitpid(2) (WEXITSTATUS(), etc.) sunt disponibile atunci când se include <stdlib.h>.

După cum s-a menționat, system() ignoră SIGINT și SIGQUIT. Acest lucru poate face ca programele care îl apelează dintr-o buclă să nu poată fi întrerupte, cu excepția cazului în care au ele însele grijă să verifice starea de ieșire a copilului. De exemplu:

    while (ceva-orice) {
        int ret = system("foo");

        if (WIFSIGNALED(ret) &&
            (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT))
                break;
    }

În conformitate cu POSIX.1, nu este specificat dacă gestionarii înregistrați folosind pthread_atfork(3) sunt apelați în timpul executării system(). În implementarea glibc, astfel de gestionari nu sunt apelați.

Înainte de glibc 2.1.3, verificarea disponibilității /bin/sh nu era efectuată dacă comandă era NULL; în schimb, se presupunea întotdeauna că este disponibil, iar system() returna întotdeauna 1 în acest caz. Începând cu glibc 2.1.3, această verificare este efectuată deoarece, chiar dacă POSIX.1-2001 cere ca o implementare conformă să furnizeze un shell, acel shell poate să nu fie disponibil sau executabil dacă programul apelant a apelat anterior chroot(2) (care nu este specificat de POSIX.1-2001).

Este posibil ca comanda shell să se încheie cu o stare de 127, ceea ce produce o valoare de returnare system() care nu poate fi distinsă de cazul în care un shell nu a putut fi executat în procesul-copil.

  Avertismente
Nu utilizați system() dintr-un program privilegiat (un program set-user-ID sau set-group-ID, sau un program cu capacități) deoarece valorile ciudate pentru unele variabile de mediu ar putea fi utilizate pentru a submina integritatea sistemului. De exemplu, PATH ar putea fi manipulată astfel încât un program arbitrar să fie executat cu privilegii. Utilizați în schimb familia de funcții exec(3), dar nu execlp(3) sau execvp(3) (care utilizează de asemenea variabila de mediu PATH pentru a căuta un executabil).

system(), de fapt, nu va funcționa corect din programe cu privilegii set-user-ID sau set-group-ID pe sisteme pe care /bin/sh este bash versiunea 2: ca măsură de securitate, bash 2 renunță la privilegii la pornire; (Debian utilizează un shell diferit, dash(1), care nu face acest lucru atunci când este invocat ca sh).

Orice intrare a utilizatorului care este utilizată ca parte a comenzii comandă ar trebui să fie cu atenție igienizată, pentru a se asigura că nu sunt executate comenzi de shell sau opțiuni de comandă neașteptate. Astfel de riscuri sunt deosebit de grave atunci când se utilizează system() dintr-un program privilegiat.

ERORI
Dacă numele comenzii începe cu o cratimă, sh(1) interpretează numele comenzii ca o opțiune, iar comportamentul este nedefinit; (consultați opțiunea -c pentru sh(1)). Pentru a rezolva această problemă, precedați comanda cu un spațiu, ca în următorul apel:

        system(" -unfortunate-command-name");

CONSULTAȚI ȘI
sh(1), execve(2), fork(2), sigaction(2), sigprocmask(2), wait(2), exec(3), signal(7)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.