/* Exemple d'illustration des primitives Unix : Un père et ses fils */ /* 1 fichier : 1 seule ouverture en écriture partagée et lseek */ #include /* entrées sorties */ #include /* pimitives de base : fork, ...*/ #include /* exit */ #include /* wait */ #include #include /* opérations sur les chaines */ #include /* opérations sur les fichiers */ #define NB_FILS 3 /* nombre de fils */ int main() { int fils, retour, desc_fic, fils_termine, wstatus, ifor; int duree_sommeil = 3; char fichier[] = "fic_res_ouv_uni_lseek.txt"; char buffer[8]; /* buffer de lecture */ bzero(buffer, sizeof(buffer)); /* ouverture du fichier en ecriture, avec autorisations rw- -r- ---*/ /* avec création si le fichier n'existe pas : O_CREAT */ /* avec vidange (raz du contenu) si le fichier existe: O_TRUNC */ desc_fic = open(fichier, O_WRONLY | O_CREAT | O_TRUNC, 0640); /* traiter systématiquement les retours d'erreur des appels */ if (desc_fic < 0) { printf("Erreur ouverture %s\n", fichier); exit(1); } printf("\nJe suis le processus principal de pid %d\n", getpid()); for (fils = 1; fils <= NB_FILS; fils++) { retour = fork(); /* Bonne pratique : tester systématiquement le retour des appels système */ if (retour < 0) { /* échec du fork */ printf("Erreur fork\n"); /* Convention : s'arrêter avec une valeur > 0 en cas d'erreur */ exit(1); } /* fils */ if (retour == 0) { /* decaler les écritures des differents fils : fils 3, fils 2, fils 1, ... */ sleep(NB_FILS - fils); /* effectuer 4 ecritures dans le fichier */ for (ifor = 1; ifor <= 4; ifor++) { // fils 2 recule la tete de 4 octets if (fils == 2) { lseek(desc_fic, -4, SEEK_CUR); } bzero(buffer, sizeof(buffer)); sprintf(buffer, "%d-%d\n", fils,ifor); write(desc_fic, buffer, strlen(buffer)); printf(" Processus fils numero %d a ecrit %s\n", fils, buffer); // fils 1 avance la tete de 4 octets if (fils == 1) { lseek(desc_fic, 4, SEEK_CUR); } sleep(duree_sommeil); } /* Important : terminer un processus par exit */ exit(EXIT_SUCCESS); /* Terminaison normale (0 = sans erreur) */ } /* pere */ else { printf("\nProcessus de pid %d a cree un fils numero %d, de pid %d \n", getpid(), fils, retour); } } /* attendre la fin des fils */ for (fils = 1; fils <= NB_FILS; fils++) { /* attendre la fin d'un fils */ fils_termine = wait(&wstatus); if WIFEXITED(wstatus) { /* fils terminé avec exit */ printf("\nMon fils de pid %d a termine avec exit %d\n", fils_termine, WEXITSTATUS(wstatus)); } else if WIFSIGNALED(wstatus) { /* fils tué par un signal */ printf("\nMon fils de pid %d a ete tue par le signal %d\n", fils_termine, WTERMSIG(wstatus)); } } close(desc_fic); printf("\nProcessus Principal termine\n"); return EXIT_SUCCESS; }