Codice PHP:
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <netinet/in.h>
void lancia_client(int);
void ricevi();
void gestione_mancanti();
void ordina_primi();
void scrivi_file();
int crea_sh_mem(key_t,int);
void *alloca_sh_mem(int);
void dealloca_sh_mem(void*);
void elimina_sh_mem(int);
int crea_init_sem(key_t,int);
void elimina_sm(int);
int sem_wait(int);
int sem_signal(int);
void inizializza_connessione();
int instaur_connessione();
void terminazione();
int porta,
primo,
ultimo,
dim,
sem,
addrlen,
ds_sock,
ds_sock_acc,
id_sh_mem;
struct sockaddr_in my_addr;
struct sockaddr addr;
char buffer[20];
main(int argc,char* argv[])
{
div_t
divisione,
dim_mem;
int
status,
chiave_sem,
chiave_memoria,
n_pac,
i,
id_shmem;
porta=atoi(argv[1]);
primo=atoi(argv[2]);
ultimo=atoi(argv[3]);
dim=atoi(argv[4]);
divisione=div((ultimo-primo),dim);
dim_mem=div((ultimo-primo),2);
chiave_memoria=10;
chiave_sem=20;
id_shmem=crea_sh_mem(chiave_memoria,(dim_mem.quot)*sizeof(int));
addr_mem=alloca_sh_mem(id_shmem);
sem=crea_init_sem(chiave_sem,1);
addr_mem[0]=1;
signal(SIGHUP,terminazione);
signal(SIGINT,terminazione);
signal(SIGQUIT,terminazione);
n_pac=divisione.quot;
if(divisione.rem!=0)
n_pac++;
inizializza_connessione();
i=primo;
while (i<ultimo)
{
if (instaura_connessione()>0)
{
printf("CONNESSIONE INSTAURATA\n");
switch (fork())
{
case -1:{printf("ERRORE NELLA FORK\n"); exit(0);}
case 0:lancia_client(0);
default:close(ds_sock_acc);
}
i=i+dim;
}
else
{
printf("CONNESSIONE FALLITA\n");
exit(1);
}
}
for (i=0;i<n_pac;i++)
wait(&status);
gestione_mancanti();
close(ds_sock);
for (i=0;i<n_pac;i++)
wait(&status);
for (i=1;i<addr_mem[0];i++)
printf("%d ",addr_mem[i]);
ordina_primi();
scrivi_file();
dealloca_sh_mem(addr_mem);
elimina_sh_mem(id_shmem);
elimina_sem(sem);
exit(0);
}
void lancia_client(int inizio)
{
int
ultimo_loc,
i;
close(ds_sock);
if (inizio<0)
{
sprintf(buffer,"%d",-inizio);
write(ds_sock_acc,buffer,20);
ultimo_loc=((div(-inizio-primo,dim)).quot+1)*dim-1;
if (ultimo_loc>ultimo)
ultimo_loc=ultimo;
sprintf(buffer,"%d",ultimo_loc);
write(ds_sock_acc,buffer,20);
}
else
{
sprintf(buffer,"%d",i);
write(ds_sock_acc,buffer,20);
if (i+dim<ultimo)
i+=dim-1;
else
i=ultimo;
sprintf(buffer,"%d",i);
write(ds_sock_acc,buffer,20);
}
ricevi();
close(ds_sock_acc);
exit(0);
}
void ricevi()
{
read(ds_sock_acc,buffer,20);
while ((strcmp(buffer,"fine")!=0)&&(strcmp(buffer,"interrupt")!=0))
{
sem_wait(sem);
addr_mem[addr_mem[0]]=atoi(buffer);
addr_mem[0]++;
sem_signal(sem);
read(ds_sock_acc,buffer,20);
}
if (strcmp(buffer,"interrupt")==0)
{
read(ds_sock_acc,buffer,20);
printf("INTERRUZIONE: RICEVO %s",buffer);
sem_wait(sem);
addr_mem[addr_mem[0]]=-atoi(buffer);
addr_mem[0]++;
sem_signal(sem);
}
}
void gestione_mancanti()
{
int j;
for (j=1;j<addr_mem[0];j++)
if (addr_mem[j]<0)
{
if(instaura_connessione()>0)
{
printf("CONNESSIONE INSTAURATA PER INTERRUZIONE\n");
switch (fork())
{
case -1:{printf("ERRORE NELLA FORK\n");exit(0);}
case 0:lancia_client(addr_mem[j]);
default:close(ds_sock_acc);
}
}
else
{
printf("CONNESSIONE FALLITA\n");
exit(1);
}
sem_wait(sem);
addr_mem[j]=0;
sem_signal(sem);
}
}
void ordina_primi()
{
int
i,
j,
tmp;
for(i=1;i<addr_mem[0]-1;i++)
for(j=i+1;j<addr_mem[0];j++)
if (addr_mem[j]<addr_mem[i])
{
tmp=addr_mem[j];
addr_mem[j]=addr_mem[i];
addr_mem[i]=tmp;
}
}
void scrivi_file()
{
int fd,
i;
fd=open("numeri.primi",O_WRONLY|O_CREAT|O_TRUNC,0666);
for (i=1;i<addr_mem[0];i++)
if ((addr_mem[i]!=0)&&(addr_mem[i]!=addr_mem[i-1]))
{
sprintf (buffer,"%d\n",addr_mem[i]);
write(fd,buffer,strlen(buffer));
}
close(fd);
}
int crea_sh_mem(key_t chiave,int n_byte)
{
id_sh_mem=shmget(chiave,n_byte,IPC_CREAT|0666);
if (id_sh_mem==-1)
{
printf("IMPOSSIBILE CREARE MEMORIA CONDIVISA CON CHIAVE %d\n",chiave);
exit(1);
}
return(id_sh_mem);
}
void* alloca_sh_mem(int id_sh_mem)
{
void* sh_mem_addr;
sh_mem_addr=shmat(id_sh_mem,0,SHM_RND);
if (sh_mem_addr==(void*)-1)
{
printf("IMPOSSIBILE ALLOCARE LA MEMORIA CONDIVISA\n");
exit(1);
}
return(sh_mem_addr);
}
void dealloca_sh_mem (void *sh_mem_addr)
{
if (shmdt(sh_mem_addr)==-1)
{
printf("IMPOSSIBILE DEALLOCARE LA MEMORIA CONDIVISA\n");
exit(1);
}
}
void elimina_sh_mem(int id_sh_mem)
{
if (shmctl(id_sh_mem,IPC_RMID,NULL)==-1)
{
printf("IMPOSSIBILE ELIMINARE LA MEMORIA CONDIVISA\n");
exit(1);
}
}
int crea_init_sem(key_t chiave, int val)
{
sem=semget(chiave,1,IPC_CREAT|0666);
if (sem==-1)
{
printf("IMPOSSIBILE CREARE IL SEMAFORO\n");
exit(1);
}
semctl(sem,0,SETVAL,val);
return(sem);
}
void elimina_sem(int id_sem)
{
if (semctl(id_sem,IPC_RMID,0)==-1)
{
printf("IMPOSSIBILE ELIMINARE IL SEMAFORO\n");
exit (1) ;
}
}
int sem_wait(int sem)
{
struct sembuf operazione[1]={{0,-1,0}};
return semop(sem,operazione,1);
}
int sem_signal(int sem)
{
struct sembuf operazione[1]={{0,+1,0}};
return semop(sem,operazione,1);
}
void inizializza_connessione()
{
ds_sock=socket(AF_INET,SOCK_STREAM,0);
if(ds_sock==-1)
exit(1);
my_addr.sin_family=AF_INET;
my_addr.sin_port=porta;
my_addr.sin_addr.s_addr=INADDR_ANY;
if(bind(ds_sock,&my_addr,sizeof(my_addr))<0)
exit(1);
listen(ds_sock,3);
}
int instaura_connessione()
{
printf("TENTATIVO DI CONNESSIONE\n");
ds_sock_acc=accept(ds_sock,&addr,&addrlen);
return(ds_sock_acc);
}
void terminazione()
{
sem_wait(sem);
ordina_primi();
scrivi_file();
kill(-1,SIGKILL);
}