151 lines
3.5 KiB
C
151 lines
3.5 KiB
C
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
#include <curses.h>
|
|
#include <ctype.h>
|
|
#include <signal.h>
|
|
#include "constantes.h"
|
|
#include "types.h"
|
|
#include "sema.h"
|
|
|
|
#define NAMESIZE 30
|
|
|
|
// nom_de_la_fenetre variable globale car je la free
|
|
// dans "quitter()"
|
|
char * nom_de_la_fenetre = NULL;
|
|
int mutex_data, mutex_tpa, i=0;
|
|
MEMP *memoireP;
|
|
|
|
void quitter(int signal);
|
|
WINDOW *creation_fenetre(int n,int d,char *t);
|
|
int main( int argc, char **argv)
|
|
{
|
|
// On ne rentre pas de numéro => on quitte en disant comment utiliser le programme
|
|
if(argc < 2) { printf("Usage %s numIPC\n", argv[0]); exit(EXIT_FAILURE); }
|
|
char c;
|
|
const char CTRL_D = 4 ;
|
|
int shmid;
|
|
|
|
// On quitte si on reçoit ces signaux
|
|
signal(SIGHUP, quitter);
|
|
signal(SIGINT, quitter);
|
|
signal(SIGQUIT, quitter);
|
|
|
|
// Récupération du numéro d'IPC
|
|
int shm_key = atoi(argv[1]);
|
|
|
|
key_t sem_key_data = MUTEX_DATA;
|
|
key_t sem_key_tpa = MUTEX_TPA;
|
|
|
|
shmid = shmget(shm_key, sizeof(MEMP), 0766);
|
|
|
|
|
|
if (shmid == -1)
|
|
{
|
|
perror("shmget");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if((memoireP = (MEMP *) shmat(shmid, 0 , 0766)) ==(void *) -1)
|
|
{
|
|
perror("shmat");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if((mutex_data = open_sem( sem_key_data)) == -1)
|
|
{
|
|
perror("open_sem");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if((mutex_tpa = open_sem( sem_key_tpa)) == -1)
|
|
{
|
|
perror("open_sem");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
P(mutex_tpa);
|
|
for(i = 0; i < MAX_PROD && memoireP->tpa[i] != -1 ; i++);
|
|
// Si on n'a plus de place dans le TPA (tous pris) alors on quitte
|
|
if(memoireP->tpa[i] != -1)
|
|
{
|
|
V(mutex_tpa);
|
|
printf("Plus de place dispo dans les producteurs\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memoireP->tpa[i] = 0;
|
|
V(mutex_tpa);
|
|
|
|
// Initialisation de la fenêtre
|
|
WINDOW * fenetre ;
|
|
|
|
initscr() ; /* initialisation (obligatoire) de curses */
|
|
noecho() ; /* suppression de l'echo des caracteres tapes*/
|
|
cbreak() ; /* lecture non bufferisee */
|
|
|
|
|
|
// Je donne un nom à ma fenêtre
|
|
nom_de_la_fenetre = (char *) malloc(sizeof(char *) * NAMESIZE);
|
|
snprintf(nom_de_la_fenetre, NAMESIZE, "PRODUCTEUR %d", i);
|
|
fenetre = creation_fenetre(LINES,0,nom_de_la_fenetre);
|
|
|
|
// On quitte le producteur en tappant CTRL_D
|
|
while (( c = wgetch(fenetre)) != CTRL_D)
|
|
{
|
|
|
|
P(mutex_data);
|
|
if(((memoireP->queue -1 + MAX_BUF) % MAX_BUF) != (memoireP->tete % MAX_BUF) )
|
|
{
|
|
memoireP->f[(memoireP->tete + MAX_BUF) % MAX_BUF].c = c;
|
|
memoireP->f[(memoireP->tete + MAX_BUF) % MAX_BUF].idp = i;
|
|
memoireP->tete = (memoireP->tete + 1 + MAX_BUF) % MAX_BUF;
|
|
}
|
|
V(mutex_data);
|
|
|
|
waddch(fenetre,c) ;
|
|
wrefresh(fenetre) ;
|
|
}
|
|
quitter(0);
|
|
}
|
|
|
|
WINDOW *creation_fenetre(int n,int d,char *t)
|
|
{
|
|
WINDOW *cadre ; /* la fenetre pour le cadre */
|
|
WINDOW *w ; /* la fenetre de dialogue */
|
|
|
|
/* creation du cadre */
|
|
|
|
cadre= newwin(n,COLS,d,0) ;
|
|
box(cadre,0,0) ;
|
|
mvwprintw(cadre,0,COLS/2-strlen(t)/2,t) ;
|
|
wrefresh(cadre) ;
|
|
|
|
/* creation de la fenetre de dialogue */
|
|
|
|
w= newwin(n-2,COLS-2,d+1,1) ;
|
|
idlok(w,TRUE) ;
|
|
scrollok(w,TRUE) ; /* mise en place du defilement (scrolling) */
|
|
wclear(w) ;
|
|
wrefresh(w) ;
|
|
return w ;
|
|
}
|
|
|
|
void quitter(int signal)
|
|
{
|
|
|
|
endwin();
|
|
// On remet la valeur de l'indice du processus à -1
|
|
// dans le tableau des producteurs
|
|
P(mutex_tpa);
|
|
memoireP->tpa[i] = -1;
|
|
V(mutex_tpa);
|
|
|
|
// On libère la mémoire de façon propre
|
|
free(nom_de_la_fenetre);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|