Difference between revisions of "Prova pratica 2015.05.20"
Jump to navigation
Jump to search
(Creata pagina con proposta di soluzione esercizio 1) |
|||
(2 intermediate revisions by one other user not shown) | |||
Line 18: | Line 18: | ||
int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
//declare a mask for signal | //declare a mask for signal | ||
sigset_t mask; | sigset_t mask; | ||
Line 32: | Line 25: | ||
//create a file descriptor for signal USR1 | //create a file descriptor for signal USR1 | ||
int signalFileDescriptor = signalfd(-1, &mask, 0); | int signalFileDescriptor = signalfd(-1, &mask, 0); | ||
− | //remove default | + | //remove default handler for SIGURS1 |
sigprocmask(SIG_BLOCK, &mask, NULL); | sigprocmask(SIG_BLOCK, &mask, NULL); | ||
struct pollfd pollstruct[2]; | struct pollfd pollstruct[2]; | ||
Line 49: | Line 42: | ||
//set event as handled | //set event as handled | ||
pollstruct[0].revents = 0; | pollstruct[0].revents = 0; | ||
− | |||
− | |||
} | } | ||
//if there is something to read in standard input | //if there is something to read in standard input | ||
Line 66: | Line 57: | ||
} | } | ||
</source> | </source> | ||
− | + | ||
+ | ==Esercizio 2== | ||
+ | <source lang="text"> | ||
+ | Ora, prendendospunto dall'esercizio 1 occorre scrivere due programmi: | ||
+ | sigsend e sigreceive. | ||
+ | Sigreceive non ha come parametri. Per prima cosa stampa il suo pid poi entra in un ciclo in cui: | ||
+ | • aspetta un segnale SIGUSR1 | ||
+ | • stampa su stdout (visualizza) il file con nome /tmp/giroXXXX (dove XXXX e' il proprio pid) | ||
+ | • cancella il file /tmp/giroXXXX | ||
+ | • Manda un segnale SIGUSR1 al processo dal quale lo ha ricevuto nella operazione due righe sopra | ||
+ | questa. | ||
+ | Sigreceive termina quando riceve in SIGUSR2. | ||
+ | Sigsend ha come parametro il pid del processo ricevente. Per ogni riga posta in input da stdin fa le seguenti azioni: | ||
+ | • crea un file /tmp/giroXXXX (dove XXXX e' il pid del processo ricevente), vi scrive la riga letta e lo chiude. | ||
+ | • Spedisce un segnale SIGUSR1 al ricevente | ||
+ | • Aspetta dallo stesso un SIGUSR1. | ||
+ | Quando lo stdin termina (^D da tastiera) manda un SIGUSR2 al ricevente. | ||
+ | All'attivazione scrive nel file il proprio pid e aspetta un segnale sigusr1.Quando riceve il segnale legge | ||
+ | Anche in questo esercizio occorre usare solo la signalfd e non la signal o la sigaction. | ||
+ | </source> | ||
+ | ===Soluzione di FedericoB=== | ||
+ | sigreceive | ||
+ | <source lang="C"> | ||
+ | #define _GNU_SOURCE | ||
+ | #include <unistd.h> | ||
+ | #include <sys/signalfd.h> | ||
+ | #include <signal.h> | ||
+ | #include <poll.h> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | int pid = getpid(); | ||
+ | printf("pid: %d\n",pid); | ||
+ | char* path; | ||
+ | //create path with format giroXXXX | ||
+ | asprintf(&path, "/tmp/giro%d", pid); | ||
+ | sigset_t mask; | ||
+ | //initialize signal mask | ||
+ | sigemptyset(&mask); | ||
+ | sigaddset(&mask, SIGUSR1); | ||
+ | sigaddset(&mask, SIGUSR2); | ||
+ | //block default handler for SIGUSR1 and SIGUSR2 | ||
+ | sigprocmask(SIG_BLOCK, &mask, NULL); | ||
+ | int fd; | ||
+ | //get a file descript for signal SIGUSR2 and SIGUS2 | ||
+ | fd = signalfd(-1,&mask,0); | ||
+ | //create a poll structur for waiting signal USR1 and USR2 | ||
+ | struct pollfd polls = {.fd = fd,.events=POLLIN}; | ||
+ | //bool for checking is a sigsr2 arrived | ||
+ | int sigusr2 = 0; | ||
+ | while (!sigusr2) { | ||
+ | //wait for signal | ||
+ | poll(&polls,1,-1); | ||
+ | //if a signal arrived | ||
+ | if (polls.revents & POLLIN) { | ||
+ | struct signalfd_siginfo siginfo; | ||
+ | //read signal information from signal file descriptor | ||
+ | read(fd, &siginfo, sizeof(struct signalfd_siginfo)); | ||
+ | if (siginfo.ssi_signo == SIGUSR1) { | ||
+ | FILE* file = fopen(path, "r"); | ||
+ | if (file!=NULL) { | ||
+ | char* buffer = malloc(50); | ||
+ | //read from file | ||
+ | fgets(buffer, 50, file); | ||
+ | //print to standard output | ||
+ | printf("%s", buffer); | ||
+ | free(buffer); | ||
+ | fclose(file); | ||
+ | //remove file | ||
+ | remove(path); | ||
+ | //send a USR2 signal to sender of signal | ||
+ | kill(siginfo.ssi_pid, SIGUSR2); | ||
+ | } else { | ||
+ | printf("Error opening the file %s \n",path); | ||
+ | } | ||
+ | } else if (siginfo.ssi_signo == SIGUSR2 ) { | ||
+ | sigusr2 = 1; | ||
+ | } | ||
+ | polls.revents = 0; | ||
+ | } | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | sigsend | ||
+ | <source lang="C"> | ||
+ | #define _GNU_SOURCE | ||
+ | #include <unistd.h> | ||
+ | #include <sys/signalfd.h> | ||
+ | #include <signal.h> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int main(int argc, char* argv[]) { | ||
+ | if (argc == 2) { | ||
+ | //get pid from program arguments | ||
+ | int receiverPid = atoi(argv[1]); | ||
+ | char* path; | ||
+ | //create path with format giroXXXX | ||
+ | asprintf(&path, "/tmp/giro%d", receiverPid); | ||
+ | char* buffer; | ||
+ | do { | ||
+ | buffer = malloc(200); | ||
+ | //read standard input | ||
+ | buffer = fgets(buffer, 200, stdin); | ||
+ | //fgets return NULL on ^D | ||
+ | if (buffer != NULL) { | ||
+ | FILE* file = fopen(path, "w"); | ||
+ | if (file != NULL) { | ||
+ | fputs(buffer, file); | ||
+ | free(buffer); | ||
+ | fclose(file); | ||
+ | //send signal SIGURS1 to receiver | ||
+ | kill(receiverPid, SIGUSR1); | ||
+ | sigset_t mask; | ||
+ | //initialize signal mask | ||
+ | sigemptyset(&mask); | ||
+ | sigaddset(&mask, SIGUSR2); | ||
+ | //block default handler for SIGUSR2 | ||
+ | sigprocmask(SIG_BLOCK, &mask, NULL); | ||
+ | int sig; | ||
+ | //wait for a SIGURS2 | ||
+ | sigwait(&mask, &sig); | ||
+ | } else { | ||
+ | printf("Error opening the file %s \n", path); | ||
+ | } | ||
+ | } | ||
+ | } while (buffer != NULL); | ||
+ | //send a SIGUSR2 to receiver | ||
+ | kill(receiverPid, SIGUSR2); | ||
+ | } else { | ||
+ | printf("Parameters error: pid required\n"); | ||
+ | } | ||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | ==Esercizio 3== | ||
+ | <source lang="text"> | ||
+ | </source> | ||
+ | ===Soluzione di G.C.=== | ||
+ | <source lang="python"> | ||
+ | import sys | ||
+ | import os | ||
+ | |||
+ | |||
+ | if __name__ == '__main__': | ||
+ | files = [f for f in os.listdir('.') if os.path.isfile(f)] | ||
+ | d = {} | ||
+ | outputList = [] | ||
+ | for f in files: | ||
+ | #all files | ||
+ | try: | ||
+ | if f == 'es3.py': | ||
+ | raise Exception() | ||
+ | with open(f,"r") as out: | ||
+ | lines = out.readlines() | ||
+ | i = 0 | ||
+ | for x in lines: | ||
+ | l = x.lstrip() | ||
+ | if l in list(d.keys()): | ||
+ | e = {} | ||
+ | e['content'] = l.strip('\n') | ||
+ | e['file'] = f | ||
+ | e['numRiga'] = i | ||
+ | outputList.append(e) | ||
+ | else: | ||
+ | d[l] = 1 | ||
+ | i +=1 | ||
+ | except: | ||
+ | print("es3.py founded!\n") | ||
+ | for x in outputList: | ||
+ | print('Nel file: %s\tAlla riga: %s\tContenuto: %s\n' % (x['file'],x['numRiga'],x['content'])) | ||
+ | </source> |
Latest revision as of 09:26, 13 May 2017
Esercizio 1
Scrivere un programma catsig che copi lo standard input nello standard output (come il comando cat senza
parametri, per intenderci) e che stampi la scritta “ho ricevuto un segnale” quando riceve un segnale SIGUSR1.
La particolarita' di questo programma e' che per la gestione dei segnali deve usare la chiamata di sistema
signalfd (e non la signal o la sigaction)
Soluzione di FedericoB
#include <unistd.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <poll.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
//declare a mask for signal
sigset_t mask;
//initialize signal mask
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
//create a file descriptor for signal USR1
int signalFileDescriptor = signalfd(-1, &mask, 0);
//remove default handler for SIGURS1
sigprocmask(SIG_BLOCK, &mask, NULL);
struct pollfd pollstruct[2];
pollstruct[0].fd = signalFileDescriptor;
pollstruct[0].events = POLLIN;
pollstruct[1].fd = STDIN_FILENO;
pollstruct[1].events = POLLIN;
while (1) {
poll(pollstruct, 2, -1);
//is signal USR1 is received
if (pollstruct[0].revents & POLLIN) {
struct signalfd_siginfo siginfo;
//read signal information from signal file descriptor
read(signalFileDescriptor, &siginfo, sizeof(struct signalfd_siginfo));
printf("ho ricevuto un segnale\n");
//set event as handled
pollstruct[0].revents = 0;
}
//if there is something to read in standard input
if (pollstruct[1].revents & POLLIN) {
char character;
//read one character until there is a character to read
while (read(fileno(stdin), &character, 1) > 0) {
//print that character to standard output
write(fileno(stdout), &character, 1);
}
//set event as handled
pollstruct[1].revents = 0;
}
}
}
Esercizio 2
Ora, prendendospunto dall'esercizio 1 occorre scrivere due programmi:
sigsend e sigreceive.
Sigreceive non ha come parametri. Per prima cosa stampa il suo pid poi entra in un ciclo in cui:
• aspetta un segnale SIGUSR1
• stampa su stdout (visualizza) il file con nome /tmp/giroXXXX (dove XXXX e' il proprio pid)
• cancella il file /tmp/giroXXXX
• Manda un segnale SIGUSR1 al processo dal quale lo ha ricevuto nella operazione due righe sopra
questa.
Sigreceive termina quando riceve in SIGUSR2.
Sigsend ha come parametro il pid del processo ricevente. Per ogni riga posta in input da stdin fa le seguenti azioni:
• crea un file /tmp/giroXXXX (dove XXXX e' il pid del processo ricevente), vi scrive la riga letta e lo chiude.
• Spedisce un segnale SIGUSR1 al ricevente
• Aspetta dallo stesso un SIGUSR1.
Quando lo stdin termina (^D da tastiera) manda un SIGUSR2 al ricevente.
All'attivazione scrive nel file il proprio pid e aspetta un segnale sigusr1.Quando riceve il segnale legge
Anche in questo esercizio occorre usare solo la signalfd e non la signal o la sigaction.
Soluzione di FedericoB
sigreceive
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int pid = getpid();
printf("pid: %d\n",pid);
char* path;
//create path with format giroXXXX
asprintf(&path, "/tmp/giro%d", pid);
sigset_t mask;
//initialize signal mask
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
//block default handler for SIGUSR1 and SIGUSR2
sigprocmask(SIG_BLOCK, &mask, NULL);
int fd;
//get a file descript for signal SIGUSR2 and SIGUS2
fd = signalfd(-1,&mask,0);
//create a poll structur for waiting signal USR1 and USR2
struct pollfd polls = {.fd = fd,.events=POLLIN};
//bool for checking is a sigsr2 arrived
int sigusr2 = 0;
while (!sigusr2) {
//wait for signal
poll(&polls,1,-1);
//if a signal arrived
if (polls.revents & POLLIN) {
struct signalfd_siginfo siginfo;
//read signal information from signal file descriptor
read(fd, &siginfo, sizeof(struct signalfd_siginfo));
if (siginfo.ssi_signo == SIGUSR1) {
FILE* file = fopen(path, "r");
if (file!=NULL) {
char* buffer = malloc(50);
//read from file
fgets(buffer, 50, file);
//print to standard output
printf("%s", buffer);
free(buffer);
fclose(file);
//remove file
remove(path);
//send a USR2 signal to sender of signal
kill(siginfo.ssi_pid, SIGUSR2);
} else {
printf("Error opening the file %s \n",path);
}
} else if (siginfo.ssi_signo == SIGUSR2 ) {
sigusr2 = 1;
}
polls.revents = 0;
}
}
return 0;
}
sigsend
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/signalfd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
if (argc == 2) {
//get pid from program arguments
int receiverPid = atoi(argv[1]);
char* path;
//create path with format giroXXXX
asprintf(&path, "/tmp/giro%d", receiverPid);
char* buffer;
do {
buffer = malloc(200);
//read standard input
buffer = fgets(buffer, 200, stdin);
//fgets return NULL on ^D
if (buffer != NULL) {
FILE* file = fopen(path, "w");
if (file != NULL) {
fputs(buffer, file);
free(buffer);
fclose(file);
//send signal SIGURS1 to receiver
kill(receiverPid, SIGUSR1);
sigset_t mask;
//initialize signal mask
sigemptyset(&mask);
sigaddset(&mask, SIGUSR2);
//block default handler for SIGUSR2
sigprocmask(SIG_BLOCK, &mask, NULL);
int sig;
//wait for a SIGURS2
sigwait(&mask, &sig);
} else {
printf("Error opening the file %s \n", path);
}
}
} while (buffer != NULL);
//send a SIGUSR2 to receiver
kill(receiverPid, SIGUSR2);
} else {
printf("Parameters error: pid required\n");
}
return 0;
}
Esercizio 3
Soluzione di G.C.
import sys
import os
if __name__ == '__main__':
files = [f for f in os.listdir('.') if os.path.isfile(f)]
d = {}
outputList = []
for f in files:
#all files
try:
if f == 'es3.py':
raise Exception()
with open(f,"r") as out:
lines = out.readlines()
i = 0
for x in lines:
l = x.lstrip()
if l in list(d.keys()):
e = {}
e['content'] = l.strip('\n')
e['file'] = f
e['numRiga'] = i
outputList.append(e)
else:
d[l] = 1
i +=1
except:
print("es3.py founded!\n")
for x in outputList:
print('Nel file: %s\tAlla riga: %s\tContenuto: %s\n' % (x['file'],x['numRiga'],x['content']))