Prova Pratica 18-06-2015
Jump to navigation
Jump to search
Esercizio1
Usando signalfd (e non signal o sigaction) scrivere due programmi tx e rx.
Rx deve essere attivato per primo e per prima cosa stampa il suo pid e aspetta.
Tx ha due parametri: il pid del ricevente rx e una stringa.
Rx deve stampare la stringa passata come secondo parametro e uscire. La stringa deve essere spedita usando solo segnali.
Ogni bit di ogni carattere deve essere inviato usando SIGUSR1 se vale 1 e SIGUSR2 se vale 0.
Al ricevimento di ogni bit rx spedisce un segnale di acknowledgement a tx che provvede a spedire il successivo
// Esercizio1: Tx
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t rx;
char *str;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
if(argc != 3)
{
printf("Usage: Tx rx string\n");
exit(1);
}
if(sscanf(argv[1],"%i",&rx) != 1)
EXIT_WITH_ERROR("sscanf");
str = argv[2];
// setto il sigset_t a contenere SIGUSR1 (sara' l'acknowledgement)
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
// annullo l'azione standard per SIGUSR1
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd");
while(1)
{
int i;
char c = *str;
// invia i bit del carattere (dal piu' al meno significativo)
for(i=7; i>=0; i--)
{
if((c>>i)&1) // prendo l'i-esimo bit di c:
{ // SIGUSR1 se e' 1
if(kill(rx,SIGUSR1) == -1)
EXIT_WITH_ERROR("kill")
}
else // SIGUSR2 se invece e' 0
{
if(kill(rx,SIGUSR2) == -1)
EXIT_WITH_ERROR("kill")
}
// attendo SIGUSR1 da Rx
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
}
if(c == 0) // esce se ha appena inviato fine-stringa
break;
str++;
}
return 0;
}
// Esercizio1: Rx
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signalfd.h>
#define EXIT_WITH_ERROR(function) \
{ \
printf("Error %i in ",errno); \
printf(function); \
printf(": %s\n",strerror(errno)); \
exit(EXIT_FAILURE); \
}
int main(int argc, char *argv[])
{
pid_t mypid;
sigset_t mask;
int sfd;
struct signalfd_siginfo siginfo;
char c;
mypid = getpid();
printf("%i\n",mypid);
// setto il sigset_t
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
// annullo l'azione standard per SIGUSR1 e SIGUSR2
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
EXIT_WITH_ERROR("sigprocmask")
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
EXIT_WITH_ERROR("signalfd")
do
{
int i;
c = 0;
// riceve 8 segnali per ogni carattere
for(i=7; i>=0; i--)
{
int len = read(sfd, &siginfo, sizeof(struct signalfd_siginfo));
if(len != sizeof(struct signalfd_siginfo))
EXIT_WITH_ERROR("read")
if (siginfo.ssi_signo == SIGUSR1) // se ho ricevuto SIGUSR1
c = c | (1 << i); // setto il bit a 1
// altrimenti e' sicuramente SIGUSR2 => il bit resta 0
kill(siginfo.ssi_pid, SIGUSR1); // invio l'acknowledgement al mittente del segnale
}
printf("%c",c);
} while(c != 0); // se tutti i bit a 0 => fine stringa
printf("\n");
return 0;
}