Skip to content

Instantly share code, notes, and snippets.

@Dysta
Created October 16, 2018 09:21
Show Gist options
  • Save Dysta/05b19665829e1d03b13e4bd8934ccfef to your computer and use it in GitHub Desktop.
Save Dysta/05b19665829e1d03b13e4bd8934ccfef to your computer and use it in GitHub Desktop.
Suivre commandes complété et fonctionnel
#define _GNU_SOURCE
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#define NCOMMANDES 4
struct sigaction sig, old;
pid_t w;
int status;
struct etat
{
pid_t pid;
char commande[10];
char arg[10];
int etat;
};
typedef struct etat* etat;
etat etat_tableau[NCOMMANDES];
char *commandes[NCOMMANDES][10]={
{"sleep","0",NULL},
{"sleep","3",NULL},
{"sleep","4",NULL},
{"sleep","5", NULL}
};
void modifier_etat(pid_t pid, int status){
int i;
for(i=0; i < NCOMMANDES ; i++)
if(etat_tableau[i]->pid == pid)
break;
if (WIFEXITED(status)) {
etat_tableau[i]->etat=0;
} else if (WIFSIGNALED(status)) {
etat_tableau[i]->etat=0;
} else if (WIFSTOPPED(status)) {
etat_tableau[i]->etat=3;
} else if (WIFCONTINUED(status)) {
etat_tableau[i]->etat=2;
}
}
void afficher_etat()
{
int i;
for ( i=0;i<NCOMMANDES;i++)
{
switch(etat_tableau[i]->etat)
{
case 3:
printf("%d : Stopped %s(%s)\n",etat_tableau[i]->pid,etat_tableau[i]->commande,etat_tableau[i]->arg);
break;
case 2:
printf("%d : Continued %s(%s)\n",etat_tableau[i]->pid,etat_tableau[i]->commande,etat_tableau[i]->arg);
break;
case 1:
printf("%d : Running %s(%s)\n",etat_tableau[i]->pid,etat_tableau[i]->commande,etat_tableau[i]->arg);
break;
case 0:
printf("%d : Terminated %s(%s)\n",etat_tableau[i]->pid,etat_tableau[i]->commande,etat_tableau[i]->arg);
break;
}
}
printf("\n");
}
void handler(int sig) {
printf("========== Reception signal -> %d : %s ==========\n", sig, strsignal(sig));
w = waitpid(0, &status, WUNTRACED | WCONTINUED | WNOHANG);
printf("pid = %d\n", w);
if (w > 0){
modifier_etat(w,status);
}
afficher_etat();
}
int reste_commande()
{
int i;
for (i=0;i<NCOMMANDES;i++)
{
if(etat_tableau[i]->etat)
return 1;
}
return 0;
}
void lancer_commandes()
{
int i;
pid_t cpid;
/* Lancement */
for(i=0; i < NCOMMANDES; i++) {
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) {
// test de fermer directement les fils
//exit(EXIT_SUCCESS);
execvp(commandes[i][0],commandes[i]);
perror("execvp");
abort();
}
etat_tableau[i]=malloc(sizeof(struct etat));
etat_tableau[i]->pid=cpid;
strcpy(etat_tableau[i]->commande,commandes[i][0]);
strcpy(etat_tableau[i]->arg,commandes[i][1]);
etat_tableau[i]->etat=1; /* en cours */
}
}
int main(int argc, char *argv[])
{
// sont devenu global
//pid_t w;
//int status;
char buf[1024];
sigset_t m, oldm;
sig.sa_flags = SA_RESTART;
sigemptyset(&sig.sa_mask);
sig.sa_handler = handler;
sigaction(SIGCHLD, &sig, &old);
sigemptyset(&m);
sigemptyset(&oldm); // pas obligé car il sert juste à save l'ancien masque
sigaddset(&m, SIGCHLD);
sigprocmask(SIG_BLOCK, &m, &oldm);
lancer_commandes();
sigprocmask(SIG_SETMASK, &oldm, NULL);
for(int cpt = 1; reste_commande(); cpt++ ) {
printf("iteration %d\n", cpt);
/* déplacé dans le handler
w = waitpid(0, &status, WUNTRACED | WCONTINUED | WNOHANG);
printf("pid = %d\n", w);
if (w > 0){
modifier_etat(w,status);
}
*/
int r = read(0,buf,1024);
if (r == -1)
perror("read");
printf("-------- Liste des zommbies ------- \n");
system("ps -eo pid,ppid,state,cmd | awk '$3==\"Z\"'");
printf("-------- Fin liste zommbies ------- \n\n");
/* déplacé dans le handler
afficher_etat();
*/
}
printf("Tous les processus se sont terminés !\n");
afficher_etat();
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment