POSIX Avant-propos POSIX = Portable Operating System Interface [for Unix]. Un p

POSIX Avant-propos POSIX = Portable Operating System Interface [for Unix]. Un programme de la norme POSIX commence par la ma- cro _POSIX_SOURCE : #define _POSIX_SOURCE 1 Compilation Fichier Makefile <cible>: <liste dependances> <commandes> Evaluation : — Analyse des prérequis (récursif) ; — Exécution des commandes. Variables : CFLAGS=-Wall -Werror Utilisation : $(CFLAGS) ($CFLAGS référence la variable v) .PHONY:all,clean : Règles ne générant pas de fichiers Compilateur GCC : 1. Préprocesseur C (cpp) : substitutions textuelles ; 2. Compilateur C (cc1) : analyses, génération, optimisa- tion ; 3. Assembleur (as) ; 4. Edition de liens (ld). Options de gcc : -ansi Respect standard ANSI -c cpp + cc1 + as ; pas ld -g Informations de déboguage -D (Define) Définir une macro -M (Make) Générer une description des dépen- dances pour chaque fichier -H (Header) Afficher le nom de chaque fichier header utilisé -I (Include) Etendre le chemin de recherche des fi- chiers headers (/usr/include) -L (Library) Etendre le chemin de recherche des li- braires (/usr/lib) -l (library) Utiliser une bibliothèque (lib<library >.a) pendant l’édition de liens -o (Output) Rediriger l’output dans un fichier (par défaut a.out) Bibliothèques statiques ar rcv maLib.a f2.o f3.o ranlib maLib.a //index Equivalent à ar rcvs maLib.a f2.o f3.o Fichiers header (*.h) Prototypes (signatures) des fonctions utilisées dans les fi- chiers *.c. Inclusion dans les fichiers *.c : #include "f2.h" //repertoire courant #include <stdlib.h> //librairie standard Définir des variables : #ifndef PI #define PI 3.14 #endif x = PI // x = 3.14 La commande gcc -DPI=3.14 créé la macro PI. Utilisation pour le debug : #ifdef DEBUG printf("Information de debug.\n"); #endif Commande gcc : gcc -DDEBUG Environnement de programmation int main(int argc, char * argv[], char ** env) — argc : nombre d’arguments (nom prog inclus) ; — argv : tableau d’arguments (argv[O] : nom prog) ; — env : variables d’environnement (couple key= value). Flux standards : — stdin (<) : entrée standard ; — stdout (>) : sortie standard ; — stderr (2>) : sortie erreur. Numéro d’erreur généré par une fonction dans une variable externe errno. Processus UNIX Définition. Correspond à l’exécution d’un programme bi- naire caractérisé par : — Numéro unique : pid ; — Utilisateur propriétaire : uid ; — Groupe de l’utilisateur propriétaire : gid ; — Répertoire courant ; — Contexte d’exécution : ▷text : code ; ▷data : données initialisées ; ▷bss : données non initialisées ; ▷heap (tas) : variables globales + malloc ; ▷stack (pile) : variables locales, paramètres ; ▷U-area : argv[], envp[]. . . Allocation dynamique de mémoire #include <stdlib.h> void * malloc(size_t size); Alloue bloc de size octets void * calloc(size_t nb, size_t size); Alloue un bloc de nb*size octets initialisés à 0 void * realloc(void * ptr, size_t size); Redimensionne un bloc mémoire (conserve son contenu) void free(void * ptr); Libère la mémoire allouée int brk(void *ptrFin); positionne la fin du tas à l’adresse ptrFin void * sbrk(intptr_t inc); Incrémente le tas de inc octets et retourne l’emplace- ment de la limite modifiée. Etats d’un processus : — Elu (running) : instructions du processus sont en train d’être exécutées ; — Bloqué (waiting) : processus en attente d’une res- source, en suspension ; — Prêt (ready) : processus en attente d’être affecté au processeur ; — Terminé (zombie) : processus fini, mais son père n’a pas pris connaissance de sa terminaison. pid_t getpid(void); Retourne le pid du processus courant pid_t getppid(void); Retourne le pid du père du processus courant Un processus est lié à un utilisateur (UID : uid_t) et à son groupe (GID : gid_t) : — Réel : droits associés à l’utilisateur/groupe qui lance le programme : ▷uid_t getuid(void); (setuid) ▷gid_t getgid(void); (seteuid) — Effectif : droits associés au programme lui-même : ▷uid_t geteuid(void); (setgid) ▷gid_t getegid(void); (setegid) Création d’un processus pid_t fork(void); Permet la création dynamique d’un nouveau processus fils qui s’exécute de façon concurrente avec le processus père qui l’a créé. Le processus fils créé est une copie du processus père. Valeur de retour : — -1 : erreur dans errno : ▷ENOMEM : plus de mémoire disponible ; ▷EAGAIN : trop de processus créés. — 0 : renvoyé au fils créé (pid du père : getpid) ; — pid du processus fils : renvoyé au père. void exit(int status); Terminaison d’un processus : — status : valeur récupérée par le processus père (disponible dans le shell avec $?) ; — Utilisation des constantes : ▷EXIT_SUCCESS = 0 ; ▷EXIT_FAILURE ̸= 0. int atexit(void (* function(void))); Insérer la fonction function en tête de la pile des fonc- tions invoquées à la fin du programme. Terminaison d’un processus (exit ou return) : — Toutes les fonctions enregistrées avec atexit() sont appelées (dépilées) ; — Fermeture des flux E/S (buffers vidés) ; — Appel à _exit() – appel système : ▷Ferme les descripteurs de fichiers ouverts ; ▷Processus père reçoit le signal SIGCHLD. — Le processus devient zombie. Synchronisation simple pid_t wait(int * status); Synchronisation père/fils : — Le processus a au moins un fils zombie : ▷Retourne : le pid de l’un de ses fils zombie ; ▷status : informations sur le fils zombie. — Le processus a des fils qui ne sont pas à l’état zombie. Le processus est bloqué jusqu’à ce que : ▷L’un de ses fils devienne zombie ; ▷Il reçoive un signal. — Le processus ne possède pas de fils : retourne -1 et errno = ECHILD Rem. Pour attendre un fils en particulier : waitpid() Macros pour la valeur de retour status : — WIFEXITED : non NULL si terminé normalement ; — WEXITEDSTATUS : code de retour si terminé norma- lement ; — WIFSIGNALED : non NULL si terminé à cause d’un signal ; — WTERMSIG : num. signal ayant terminé le proces- sus ; — WIFSTOPPED : non NULL si processus fils stoppé ; — WSTOPSIG : num. signal ayant stoppé le processus. pid_t waitpid(pid_t pid, int * status, int opt) Tester la terminaison d’un processus fils d’identité pid ou du groupe |pid| : — Valeur de retour : ▷-1 : erreur ; ▷0 : processus non terminé (mode non blo- quant) ; ▷pid du processus terminé. — Paramètre pid : ▷> 0 : processus fils ; ▷0 : processus fils qcq (même groupe appe- lant) ; ▷-1 : processus fils qcq ; ▷< -1 : processus fils qcq du groupe |pid|. — Paramètre opt : ▷WNOHANG : appel non bloquant ; ▷WUNTRACED : retourne si le processus est stoppé. Recouvrement de code (exec) Même pid, même processus, code différent. Forme sous laquelle les arguments argv sont transmis : — v : argv sous forme de tableau (v - vector) ; — l : argv sous forme de liste. Rem. NULL à la fin. Transmission de paramètres : — p : exécutable recherché dans le PATH ; — e : prend en paramètre un nouvel environnement. Erreurs (errno) : — EACCES : pas de permission d’accès au fichier ; — ENOENT : fichier n’a pas été trouvé. int execl (const char *path, const char *arg, ...) int execlp(const char *file, const char *arg, ...) int execle(const char *path, const char *arg, ..., char * const envp[]) int execv (const char *path, char * const argv[]) int execvp(const char *file, char * const argv[]) int execve(const char *path, char * const argv[], char * const envp[]) Autres fonctions int system(const char *command); Invoque le shell en lui transmettant la fonction passée en paramètre : — fork() et le fils lance la commande ; — Le père attend le fils. pid_t vfork(void); Idem fork, mais le segment de données n’est pas du- pliqué. Le processus fils travaille sur les données de son père ⇒Bloquer le père en attente du fils. int setjmp(jmp_buf env); Permet de sauvegarder l’état du programme dans env du type jmp_buf : — Premier appel : 0 ; — Appel issu d’un longjmp : valeur de lonjmp. void longjmp(jmp_buf env, int val); Remet le programme dans l’état sauvegardé par le der- nier appel à setjmp par rapport à la variable env. Signaux Définition. Un signal est une information transmise à un programme durant son exécution : — Signal →int (̸= 0, < NSIG) ; — Communication OS ↔Processus : ▷En cas d’erreur (violation mémoire, erreur d’E/S) ; ▷Par l’utilisateur : ctrl-C, ctrl-Z, . . . ; ▷Déconnexion de la ligne/terminal, etc. — Possibilité d’envoi d’un signal entre processus ; — Traitement par défaut en général : quitter le proces- sus. Liste des signaux kill -l Envoyer un signal kill -KILL <pid>; kill -INT <pid> Définition (Signal pendant). Signal envoyé à un processus mais qui n’a pas encore été pris en compte. Définition (Signal masqué/bloqué). Délivrance du signal ajournée. Définition (Délivrance). Le processus prend en compte le signal et réalise l’action qui lui est associée (état noyau → état utilisateur) : — Terminaison du processus ; — Terminaison du processus avec production d’un fi- chier de nom core ; — Signal ignoré ; — Suspension du processus (stopped ou suspended) ; uploads/Industriel/ posix-refcard.pdf

  • 27
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager