Sunteți pe pagina 1din 4

SUBIECT EXAMEN PSO

SPECIFICAȚII:

a) Aplicația presupune existența a minim 2 threaduri secundare care vor loga (înregistra) diverse informații într-
un fișier de log din directorul curent denumit “app.log”.

b) Pe TOATĂ durata execuției, aplicația nu va putea fi întreruptă de semnalele SIGTERM și SIGINT.

c) Pentru închiderea în condiții de siguranță (“safe”) a aplicației se va transmite semnalul SIGUSR1 din exteriorul
procesului. Handlerul pentru SIGUSR1 va fi stabilit în cadrul threadului de afișare.

d) Primul thread secundar lansat în execuție este threadul de afișare care va scrie, în fișierul app.log, data și ora
curentă (app_ini_time – obținut la pornirea aplicației) iar apoi va afișa, la intervale de 3 secunde, un caracter în terminal.

e) Cel de-al doilea thread secundar este cel de monitorizare. Threadul de monitorizare va trebui să urmărească
autentificările reușite în sistem prin verificarea conținutului fișierului de log /var/log/lastlog. Fișierul de log este
interpretat cu ajutorul programului /usr/bin/lastlog (comanda lastlog disponibilă în PATH). Fișierul lastlog conține, pe
fiecare linie, fiecare utilizator din sistem și data, ora, portul și terminalul/consolă virtual/ă din care s-a făcut ultima
autentificare cu succes. Thread-ul de monitorizare va putea porni până la MAX_THR_VERIFICARE thread-uri de verificare.

f) Dacă, în fișierul de log /var/log/lastlog, se depistează o autentificare mai recentă (auth_time) decât momentul
pornirii aplicației (se compară auth_time din fișierul lastlog cu app_ini_time obținut la pornirea aplicației), threadul de
monitorizare:

f.1) va scrie evenimentul în fișierul app.log (utilizator – data și ora)

f.2) va lansa în execuție un thread secundar nou, denumit în continuare “thread de verificare”

f.3) va transmite semnalul SIGUSR1 către threadul de afișare care va afișa în terminal
“Threadul de afisare a primit semnalul SIGUSR1. Un thread de verificare a fost creat”
g) Threadul de verificare va trebui să verifice, la intervale de 10 secunde, dacă au apărut modificări în directorul
home al utilizatorului depistat de threadul de monitorizare. Dacă threadul de verificare depistează o modificare a
directorului home al utilizatorului de la momentul pornirii aplicației, va înregistra acest eveniment în fișierul app.log și va
notifica threadul de afișare asupra acestui eveniment prin intermediul unui semafor. Threadul de afișare va primi
această notificare și va afișa in terminal mesajul “---New event logged---”.

Exemplu output în terminal:

Exemplu app.log:

CERINȚE:

1) (1,5 p) Crearea fișierului de configurare pentru utilitarul make în vederea compilării aplicației.
all: solutie
solutie: src/threads.o src/main.o
gcc -Wall -pthread src/threads.o src/main.o -o solutie
src/threads.o: src/threads.c
gcc -Wall -Iinclude -c src/threads.c -o src/threads.o
src/main.o: src/main.c
gcc -Wall -Iinclude -c src/main.c -o src/main.o
clean:
-rm -rf *.o solutie
-rm -rf src/*.o

2) (1,0 p) Îndeplinirea specificației b).


sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGTERM);
sigprocmask(SIG_BLOCK, &sigset, NULL);
3) (0,5 p) Activarea handlerului pentru primirea semnalului SIGUSR1, conform specificației c).
signal(SIGUSR1, sigusr1_handler); //cerinta #3

4) (3,0 p) Lansarea corectă a threadurilor (la momentele corecte de timp în execuția aplicației pentru îndeplinirea
specificațiilor d), e) și f.2)) și așteptarea acestora pentru o terminare sigură a execuției lor.
pthread_create(&tid_afisare, NULL, thread_afisare, NULL); // cerinta 4
pthread_join(tid_afisare, NULL); // cerinta 4

pthread_create(&tid_monitorizare, NULL, thread_monitorizare, NULL); //cerinta #4

pthread_join(tid_monitorizare, NULL); //cerinta #4

pthread_create(&tid_verificare[nr_thr_verificare++], NULL, thread_verificare,


(void*)username); //cerinta #4

for (int i = 0; i< nr_thr_verificare; i++) //cerinta #4


pthread_join(tid_verificare[i], NULL); //cerinta #4

5) (1,5 p) Asigurați accesul threadurilor la fișierul app.log astfel încât operațiunile de scriere să nu fie întrerupte.
pthread_mutex_lock(&log_mutex); //cerinta #5
write(log_fd, "T_afis -> ", 10);
write(log_fd, ascii_time, strlen(ascii_time));
pthread_mutex_unlock(&log_mutex); //cerinta #5

pthread_mutex_lock(&log_mutex); //cerinta #5
write(log_fd, print_msg, strlen(print_msg));
pthread_mutex_unlock(&log_mutex); //cerinta #5

pthread_mutex_lock(&log_mutex); //cerinta #5
write(log_fd, print_buffer, strlen(print_buffer));
pthread_mutex_unlock(&log_mutex); //cerinta #5

6) (1,0 p) Care este motivul pentru care este utilizat în aplicație mutexul close_app_mutex ? Care este utilitatea
pipe-ului în această aplicație (cum este utilizat)?
- accesul exclusiv la variabila close_app care determină stările aplicației ce trebuie verificate
atât pe durata execuției de către threadurile secundare, precum și în cadrul handlerului desemnat
pentru semnalul SIGUSR1; dacă nu s-ar garanta accesul exclusiv folosind mutexul, ar putea exista
situația unei tranziții între stări la momentul verificării variabilei de către 2 threaduri,
simultan

- pipe-ul a fost utilizat pentru asigurarea mecanismului de comunicației cu procesul nou creat
care rulează comanda lastlog; outputul comenzii lastlog va fi transmis prin pipe către procesul
rulează aplicația și va fi preluat de către threadul de monitorizare prin funcția de parsare

7) (0,5 p) Semnalizarea threadului de afișare conform specificației f.3) .


pthread_kill(tid_afisare, SIGUSR1); //cerinta #7

1,0 p – oficiu

Timp de lucru alocat – 75min

----- INSTRUCTIUNI DE REZOLVARE/EDITARE -----


ATENȚIE !

Pentru fiecare cerință, veți comenta la sfârșitul fiecărei linii care contribuie la rezolvarea acesteia, astfel:

pentru rezolvarea cerinței 3 :


random_var=random_function(); //cerinta #3

...

random_var2=random_function(); //cerinta #3

La finalul timpului de lucru alocat sau la finalizare rezolvării, veți preda un director care va conține, după caz, 4 fișiere:

- Fișierul threads.c completat de voi conform cerințelor


- Fișierul main.c completat de voi conform cerințelor
- Fișierul Makefile afferent cerinței 1
- Fișierul Cerinta6.txt cu răspunsurile la cerința 6

Directorul va fi denumit NumeStudent_PrenumeStudent_grupa ( Ex Chindris_Cristian_D Anastasiei_Emil_A )

Numele de fișiere și directoare NU TREBUIE SĂ CONȚINĂ SPAȚII întrucât vor fi prelucrate automat și trecute printr-o
aplicație de anti-plagiat. Fișierele care nu trec prin aplicație din cauza nerespectării formatului NU vor fi luate în
considerare.

S-ar putea să vă placă și