Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so:laboratoare:laborator-03 [2019/03/03 20:20]
dragos_florin.costea
so:laboratoare:laborator-03 [2022/03/02 09:31] (current)
teodor_stefan.dutu [Exercițiul -1 - GSOC] Replace with Stagii pe bune
Line 2: Line 2:
 ===== Materiale ajutătoare ===== ===== Materiale ajutătoare =====
  
-  * [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab03-slides.pdf | lab03-slides.pdf]] 
-  * [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab03-refcard.pdf | lab03-refcard.pdf]] 
   * [[http://​elf.cs.pub.ro/​so/​res/​tutorial/​lab-03-procese/​|Video Procese]]   * [[http://​elf.cs.pub.ro/​so/​res/​tutorial/​lab-03-procese/​|Video Procese]]
  
Line 9: Line 7:
   * TLPI - Chapter 6, ''​Processes'',​ Chapter 26 ''​Monitoring Child Processes''​   * TLPI - Chapter 6, ''​Processes'',​ Chapter 26 ''​Monitoring Child Processes''​
   * WSP4 - Chapter 6, ''​Process Management''​   * WSP4 - Chapter 6, ''​Process Management''​
 +
 +===== Link-uri către secțiuni utile =====
 +==== Linux ====
 +  * [[#Crearea unui proces în Linux|Crearea unui proces]]
 +  * [[#​Înlocuirea imaginii unui proces în Linux|Înlocuirea imaginii unui proces]]
 +  * [[#​Așteptarea terminării unui proces în Linux|Așteptarea terminării unui proces]]
 +  * [[#​Terminarea unui proces în Linux|Terminarea unui proces]]
 +  * [[#Exemplu (my_system)|Exemplu (my_system)]]
 +  * [[#Copierea descriptorilor de fișier|Copierea descriptorilor de fișier]]
 +  * [[#​Moștenirea descriptorilor de fișier după operații fork/​exec|Moștenirea descriptorilor de fișier după operații fork/exec]]
 +  * [[#​Variabile de mediu în Linux|Variabile de mediu în Linux]]
 +  * [[#Pipe-uri anonime în Linux|Pipe-uri anonime în Linux]]
 +  * [[#Pipe-uri cu nume în Linux|Pipe-uri cu nume în Linux]] ​
 +==== Windows ====
 +  * [[#Crearea unui proces în Windows|Crearea unui proces]]
 +  * [[#​Așteptarea terminării unui proces în Windows|Așteptarea terminării unui proces]]
 +  * [[#Aflarea codului de terminare a procesului așteptat în Windows|Aflarea codului de terminare a procesului așteptat]]
 +  * [[#​Terminarea unui proces în Windows|Terminarea unui proces]]
 +  * [[#​Exemplu|Exemplu]]
 +  * [[#​Moștenirea handle-urilor la CreateProcess|Moștenirea handle-urilor la CreateProcess]]
 +  * [[#​Variabile de mediu în Windows|Variabile de mediu în Windows]]
 +  * [[#Pipe-uri anonime în Windows|Pipe-uri anonime în Windows]]
 +  * [[#Pipe-uri cu nume în Windows|Pipe-uri cu nume în Windows]]
  
 ===== Prezentare concepte ===== ===== Prezentare concepte =====
Line 45: Line 66:
   *Se creează un nou proces cu ''​fork''​ - procesul copil are o copie a resurselor procesului părinte. ​   *Se creează un nou proces cu ''​fork''​ - procesul copil are o copie a resurselor procesului părinte. ​
   *Dacă se dorește înlocuirea imaginii procesului copil aceasta poate fi schimbată prin apelarea unei funcții din familia ''​exec*''​.   *Dacă se dorește înlocuirea imaginii procesului copil aceasta poate fi schimbată prin apelarea unei funcții din familia ''​exec*''​.
-==== Crearea unui proces ====+==== Crearea unui proces ​în Linux ====
  
 În UNIX un proces se creează folosind apelul de sistem [[http://​linux.die.net/​man/​2/​fork|fork]]:​ În UNIX un proces se creează folosind apelul de sistem [[http://​linux.die.net/​man/​2/​fork|fork]]:​
Line 77: Line 98:
 </​code>​ </​code>​
  
-==== Înlocuirea imaginii unui proces ====+==== Înlocuirea imaginii unui proces ​în Linux ====
  
  
Line 113: Line 134:
  
 Toate funcțiile ''​exec*''​ sunt implementate prin apelul de sistem [[http://​linux.die.net/​man/​2/​execve|execve]]. Toate funcțiile ''​exec*''​ sunt implementate prin apelul de sistem [[http://​linux.die.net/​man/​2/​execve|execve]].
-==== Așteptarea terminării unui proces ====+==== Așteptarea terminării unui proces ​în Linux ====
  
 Familia de funcții [[http://​linux.die.net/​man/​3/​waitpid|wait]] suspendă execuția procesului apelant până când procesul (procesele) specificat în argumente fie s-a terminat, fie a fost oprit (''​SIGSTOP''​). Familia de funcții [[http://​linux.die.net/​man/​3/​waitpid|wait]] suspendă execuția procesului apelant până când procesul (procesele) specificat în argumente fie s-a terminat, fie a fost oprit (''​SIGSTOP''​).
Line 135: Line 156:
 </​code>​ </​code>​
  
-==== Terminarea unui proces ====+==== Terminarea unui proces ​în Linux ====
  
  
Line 177: Line 198:
 <​note>​ Conform ''​ISO C'',​ un program care se termină cu ''​return x''​ din ''​main()''​ va avea același comportament ca unul care apelează ''​exit(x)''​. </​note>​ <​note>​ Conform ''​ISO C'',​ un program care se termină cu ''​return x''​ din ''​main()''​ va avea același comportament ca unul care apelează ''​exit(x)''​. </​note>​
  
-Un proces al cărui părinte s-a terminat poartă numele de **proces orfan**. Acest proces este adoptat automat de către procesul ''​init'',​ dar poartă denumirea de orfan în continuare deoarece procesul care l-a creat inițial nu mai există.+Un proces al cărui părinte s-a terminat poartă numele de **proces orfan**. Acest proces este adoptat automat de către procesul ''​init'',​ dar poartă denumirea de orfan în continuare deoarece procesul care l-a creat inițial nu mai există. ​În acest context, procesul ''​init''​ implementează funcționalitatea de **child reaper**. 
 + 
 +<​note>​ 
 +Pe distribuțiile de Linux recente, funcționalitatea de child reaper poate fi implementată și de alte procese din sistem, precum ''​systemd''​. 
 +</​note>​
  
 Un proces finalizat al cărui părinte nu a citit (încă) statusul terminării acestuia poartă numele de **proces zombie**. Procesul intră într-o stare de terminare, iar informația continuă să existe în tabela de procese astfel încât să ofere părintelui posibilitatea de a verifica codul cu care s-a finalizat procesul. În momentul în care părintele apelează funcția ''​wait'',​ informația despre proces dispare. Orice proces copil o să treacă prin starea de proces zombie la terminare. Un proces finalizat al cărui părinte nu a citit (încă) statusul terminării acestuia poartă numele de **proces zombie**. Procesul intră într-o stare de terminare, iar informația continuă să existe în tabela de procese astfel încât să ofere părintelui posibilitatea de a verifica codul cu care s-a finalizat procesul. În momentul în care părintele apelează funcția ''​wait'',​ informația despre proces dispare. Orice proces copil o să treacă prin starea de proces zombie la terminare.
Line 375: Line 400:
  
 ===== Procese în Windows ===== ===== Procese în Windows =====
-==== Crearea unui proces ====+ 
 +==== Crearea unui proces ​în Windows ​====
  
 În Windows, atât crearea unui nou proces, cât și înlocuirea imaginii lui cu cea dintr-un program executabil se realizează prin apelul funcției [[http://​msdn.microsoft.com/​en-us/​library/​ms682425.aspx|CreateProcess]]. În Windows, atât crearea unui nou proces, cât și înlocuirea imaginii lui cu cea dintr-un program executabil se realizează prin apelul funcției [[http://​msdn.microsoft.com/​en-us/​library/​ms682425.aspx|CreateProcess]].
Line 459: Line 485:
  
  
-==== Așteptarea terminării unui proces ====+==== Așteptarea terminării unui proces ​în Windows ​====
  
 Pentru a suspenda execuția procesului curent până când unul sau mai multe alte procese se termină, se va folosi una din funcțiile de așteptare [[http://​msdn.microsoft.com/​en-us/​library/​ms687032.aspx|WaitForSingleObject]] ori [[http://​msdn.microsoft.com/​en-us/​library/​ms687025.aspx|WaitForMultipleObjects]]. Pentru a suspenda execuția procesului curent până când unul sau mai multe alte procese se termină, se va folosi una din funcțiile de așteptare [[http://​msdn.microsoft.com/​en-us/​library/​ms687032.aspx|WaitForSingleObject]] ori [[http://​msdn.microsoft.com/​en-us/​library/​ms687025.aspx|WaitForMultipleObjects]].
Line 477: Line 503:
 Funcțiile de așteptare sunt folosite în cadrul mai general al mecanismelor de sincronizare între procese. Mai multe detalii pot fi găsite [[ so:​laboratoare-2013:​laborator-05 | aici]]. Funcțiile de așteptare sunt folosite în cadrul mai general al mecanismelor de sincronizare între procese. Mai multe detalii pot fi găsite [[ so:​laboratoare-2013:​laborator-05 | aici]].
  
-==== Aflarea codului de terminare a procesului așteptat ====+==== Aflarea codului de terminare a procesului așteptat ​în Windows ​====
  
 Pentru a determina codul de eroare cu care s-a terminat un anumit proces, se va apela funcția [[http://​msdn.microsoft.com/​en-us/​library/​ms683189.aspx|GetExitCodeProcess]]:​ Pentru a determina codul de eroare cu care s-a terminat un anumit proces, se va apela funcția [[http://​msdn.microsoft.com/​en-us/​library/​ms683189.aspx|GetExitCodeProcess]]:​
Line 491: Line 517:
   *dacă procesul se termină cu succes valoarea întoarsă în ''​lpExitCode''​ va fi 0 sau 1 în caz de eroare.   *dacă procesul se termină cu succes valoarea întoarsă în ''​lpExitCode''​ va fi 0 sau 1 în caz de eroare.
  
-==== Terminarea unui proces ====+==== Terminarea unui proces ​în Windows ​====
  
 Pentru terminarea procesului curent, Windows API pune la dispoziție funcția [[http://​msdn.microsoft.com/​en-us/​library/​ms682658(VS.85).aspx | ExitProcess]]. Pentru terminarea procesului curent, Windows API pune la dispoziție funcția [[http://​msdn.microsoft.com/​en-us/​library/​ms682658(VS.85).aspx | ExitProcess]].
Line 570: Line 596:
     bRes = GetExitCodeProcess(pi.hProcess,​ &​dwRes);​     bRes = GetExitCodeProcess(pi.hProcess,​ &​dwRes);​
     DIE(bRes == FALSE, "​GetExitCode"​);​     DIE(bRes == FALSE, "​GetExitCode"​);​
 +    ​
 +    CloseProcess(&​pi); ​   ​
  
     return 0;     return 0;
Line 736: Line 764:
  
 [[http://​msdn.microsoft.com/​en-us/​library/​aa910675.aspx|WriteFile]] se termină atunci când toți octeții au fost scriși. Dacă bufferul pipe-ului este plin înainte ca toți octeții să fie scriși, [[http://​msdn.microsoft.com/​en-us/​library/​aa910675.aspx|WriteFile]] rămâne blocat până când alt proces sau thread folosește [[http://​msdn.microsoft.com/​en-us/​library/​aa914377.aspx|ReadFile]] pentru a face loc în buffer. [[http://​msdn.microsoft.com/​en-us/​library/​aa910675.aspx|WriteFile]] se termină atunci când toți octeții au fost scriși. Dacă bufferul pipe-ului este plin înainte ca toți octeții să fie scriși, [[http://​msdn.microsoft.com/​en-us/​library/​aa910675.aspx|WriteFile]] rămâne blocat până când alt proces sau thread folosește [[http://​msdn.microsoft.com/​en-us/​library/​aa914377.aspx|ReadFile]] pentru a face loc în buffer.
 +
 +Un pipe anonim este considerat închis doar când ambele capete ale sale, cel de citire și cel de scriere, sunt închise prin intermediul funcției [[https://​docs.microsoft.com/​en-us/​windows/​desktop/​api/​handleapi/​nf-handleapi-closehandle|CloseHandle]]. ​
  
 Pipe-urile anonime sunt implementate folosind un pipe cu nume unic. De aceea se poate pasa un handle al unui pipe anonim unei funcții care cere un handle al unui pipe cu nume. Pipe-urile anonime sunt implementate folosind un pipe cu nume unic. De aceea se poate pasa un handle al unui pipe anonim unei funcții care cere un handle al unui pipe cu nume.
Line 832: Line 862:
 </​spoiler>​ </​spoiler>​
  
 +===== Sumar =====
  
-===== Exerciții =====+^  **Operație**  ^  **Linux** ​ ^  **Windows** ​ ^ 
 +|  Crearea unui proces ​ |  [[#​crearea_unui_proces_in_linux | fork() ​ ]]  |  [[#​crearea_unui_proces_in_windows| CreateProcess() ]]  | 
 +|  Așteptarea terminării unui proces ​ |  [[#​asteptarea_terminarii_unui_proces_in_linux| wait()]], [[#​asteptarea_terminarii_unui_proces_in_linux| waitpid()]] ​ |  [[#​asteptarea_terminarii_unui_proces_in_windows | WaitForSingleObject()]] ​ | 
 +|  Înlocuirea imaginii unui process ​ |  [[#​inlocuirea_imaginii_unui_proces_in_linux | exec() ]]  |  -  | 
 +|  Terminarea unui process ​ |  [[#​terminarea_unui_proces_in_linux| exit()]] ​ |  [[#​terminarea_unui_proces_in_windows| ExitProcess() ]]  | 
 +|  Moștenirea descriptorilor de fișier ​ |  [[#​mostenirea_descriptorilor_de_fisier_dupa_operatii_forkexec | dup() + exec() ]]   ​| ​ [[#​mostenirea_handle-urilor_la_createprocess | CreateProcess() ]], care are câmpul ''​bInheritHandle''​ al structurii ''​SECURITY_ATTRIBUTES''​ setat pe ''​TRUE'' ​ | 
 +|  Variabile de mediu  |  [[#​variabile_de_mediu_in_linux | getenv()]], [[#​variabile_de_mediu_in_linux | setenv()]] ​ |   ​[[#​variabile_de_mediu_in_windows |GetEnvironmentVariable() ]], [[#​variabile_de_mediu_in_windows | SetEnvironmentVariable() ]]  |  
 +|  Pipe anonim ​ |  [[#​pipe-uri_anonime_in_linux | pipe()]] ​ |  [[#​pipe-uri_anonime_in_windows | CreatePipe() ]]  | 
 +|  Pipe cu nume  |  [[#​pipe-uri_cu_nume_in_linux | mkfifo()]] ​ |  [[#​pipe-uri_cu_nume_in_windows | CreateNamedPipe() ]]  |
  
-În rezolvarea laboratorului folosiți arhiva de sarcini [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab03-tasks.zip | lab03-tasks.zip]] 
  
-<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile.</​note>​ 
  
-==== Exercițiul -1 - GSOC ==== 
-Google Summer of Code este un program de vară în care studenții 
-(indiferent de anul de studiu) sunt implicați în proiecte Open Source 
-pentru a își dezvolta skill-urile de programare, fiind răsplătiți cu o 
-bursă a cărei valoare [[https://​developers.google.com/​open-source/​gsoc/​help/​student-stipends|depinde de țară]] 
-([[https://​developers.google.com/​open-source/​gsoc|pagină principală GSOC]]). 
  
-UPB se află în top ca număr de studenți acceptați; în fiecare an fiind 
-undeva la aprox. 30-40 de studenți acceptați. 
-Vă încurajăm să aplicați! Există și un grup de fb cu foști 
-participanți unde puteti să îi contactați pentru sfaturi 
-[[https://​www.facebook.com/​groups/​240794072931431/​|facebook page]] 
  
  
-==== Exercițiul 0 - Joc interactiv (2p) ==== 
  
-  * Detalii desfășurare [[http://​ocw.cs.pub.ro/​courses/​so/​meta/​notare#​joc_interactiv|joc]]. 
  
  
-===== Linux (5p) ===== 
  
-==== Exercițiul ​system (1.5p) ====+ 
 + 
 + 
 + 
 +===== Exerciții ===== 
 + 
 +<note important>​ 
 +În cadrul laboratoarelor vom folosi repository-ul de git al materiei SO - https://​github.com/​systems-cs-pub-ro/​so. Va trebui sa clonați repository-ul pe masinile virtuale folosind comanda: ''​git clone https://​github.com/​systems-cs-pub-ro/​so''​. Dacă doriți să descărcați repositoryul în altă locație, folosiți comanda ''​git clone https://​github.com/​systems-cs-pub-ro/​so ${target}''​. 
 + 
 +Pentru a actualiza repository-ul,​ folosiți comanda ''​git pull origin master''​ din interiorul directorului în care se află repository-ul. Recomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentă.În cazul în care gitul detectează conflicte la nivelul vreunui fişier, folosiți următoarele comenzi pentru a vă păstra modificările:​ 
 +<​code>​ 
 +git stash 
 +git pull origin master 
 +git stash pop 
 +</​code>​ 
 + 
 +Pentru mai multe informații despre folosirea utilitarului git, urmați ghidul de la https://​gitimmersion.com. 
 +</​note>​ 
 + 
 +<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile.</​note>​ 
 + 
 +==== Exercițiul ​Stagii pe bune ==== 
 + 
 +[[https://​stagiipebune.ro/​students/​jobs/​|Stagii pe bune]] este o platformă de internshipuri care vrea să ușureze și să uniformizeze procesul prin care puteți aplica la companii din România (București,​ Iași, Cluj și Timișoara). Facultatea de Automatică și Calculatoare are un parteneriat cu Stagii pe bune și vă încurajăm să le folosiți platforma pentru a aplica la internshipuri!  
 + 
 +Stagii pe bune organizează și evenimente de prezentare a celor mai mari companii din România. Pentru a fi la curent cu acestea, urmăriți și anunțurile postate de Stagii pe bune pe [[https://​www.facebook.com/​stagiipebune|Facebook]]. 
 + 
 +===== Linux ===== 
 + 
 +==== Exercițiul 1 - system ​====
  
 Intrați în directorul ''​1-system''​. ​ Intrați în directorul ''​1-system''​. ​
Line 878: Line 930:
       * cițiți pagina de manual [[http://​linux.die.net/​man/​1/​strace|strace]]       * cițiți pagina de manual [[http://​linux.die.net/​man/​1/​strace|strace]]
  
-Revedeți secțiunea [[#​Înlocuirea imaginii unui proces|Înlocuirea imaginii unui proces]] și pagina de manual pentru [[http://​linux.die.net/​man/​2/​execve | execve ]].+Revedeți secțiunea [[#​Înlocuirea imaginii unui proces ​în Linux |Înlocuirea imaginii unui proces ​în Linux]] și pagina de manual pentru [[http://​linux.die.net/​man/​2/​execve | execve ]].
  
-==== Exercițiul 2 - orphan ​(1p) ====+==== Exercițiul 2 - orphan ====
  
 Intrați în directorul ''​2-orphan''​ și inspectați sursa ''​orphan.c''​. ​ Intrați în directorul ''​2-orphan''​ și inspectați sursa ''​orphan.c''​. ​
Line 893: Line 945:
  
  
-==== Exercițiul 3 - Tiny-Shell ​(2.5p) ​====+==== Exercițiul 3 - Tiny-Shell ====
  
 Intrați în directorul ''​3-tiny''​. Intrați în directorul ''​3-tiny''​.
Line 901: Line 953:
 //​Observație://​ Pentru a ieși din tiny shell folosiți ''​exit''​ sau ''​CTRL+D''​. //​Observație://​ Pentru a ieși din tiny shell folosiți ''​exit''​ sau ''​CTRL+D''​.
  
-=== 3a. Execuția unei comenzi simple ​(0.5p) ​===+=== 3a. Execuția unei comenzi simple ===
  
 Creați un nou proces care să execute o comandă simplă. Creați un nou proces care să execute o comandă simplă.
Line 913: Line 965:
 > exit </​code>​ > exit </​code>​
  
-=== 3b. Adăugare suport pentru setarea și expandarea variabilelor de mediu (1p) ===+=== 3b. Adăugare suport pentru setarea și expandarea variabilelor de mediu ===
  
 Trebuie să completați funcțiile ''​set_var''​ și ''​expand'';​ acestea sunt apelate deja atunci când se face parsarea liniei de comandă. Verificarea erorilor trebuie făcută în aceaste funcții. Trebuie să completați funcțiile ''​set_var''​ și ''​expand'';​ acestea sunt apelate deja atunci când se face parsarea liniei de comandă. Verificarea erorilor trebuie făcută în aceaste funcții.
Line 924: Line 976:
 > echo $name  </​code>​ > echo $name  </​code>​
  
-=== 3c. Redirectarea ieșirii standard ​(1p) ===+=== 3c. Redirectarea ieșirii standard ===
  
 Completați funcția ''​do_redirect''​ astfel încât tiny-shell trebuie să suporte redirectarea output-ului unei comenzi (stdout) într-un fișier. Completați funcția ''​do_redirect''​ astfel încât tiny-shell trebuie să suporte redirectarea output-ului unei comenzi (stdout) într-un fișier.
Line 937: Line 989:
 > cat out > cat out
 </​code>​ </​code>​
-===== Windows ​(4p) =====+===== Windows =====
  
-<note important>​ Pentru exerciţiul **Tiny-Shell on Windows** compilarea se va realiza din Visual Studio sau din command-prompt-ul de Visual Studio, iar rularea executabilului ''​tiny.exe''​ se va realiza din **Cygwin**.+<note important>​ Pentru exerciţiul **Tiny-Shell on Windows** compilarea se va realiza din Visual Studio sau din command-prompt-ul de Visual Studio, iar rularea executabilului ''​.\2-tiny.exe''​ se va realiza din **Cygwin**.
      * Pentru a ajunge din Cygwin pe Desktop (atenție la folosirea apostrofurilor):<​code bash>      * Pentru a ajunge din Cygwin pe Desktop (atenție la folosirea apostrofurilor):<​code bash>
 $ cd '​C:​\Users\Student\Desktop'​ $ cd '​C:​\Users\Student\Desktop'​
Line 945: Line 997:
 </​note>​ </​note>​
  
-==== Exercițiul 1 - Bomb (0.5p) ​====+==== Exercițiul 1 - Bomb ====
 Deschideți proiectul (fișierul ''​.sln''​) și compilați primul subproiect: ''​1-bomb''​. Deschideți proiectul (fișierul ''​.sln''​) și compilați primul subproiect: ''​1-bomb''​.
  
Line 951: Line 1003:
  
 <note warning> NU executați 1-bomb.exe </​note>​ <note warning> NU executați 1-bomb.exe </​note>​
-==== Exercițiul 2 - Tiny-Shell on Windows ​(3.5p) ​====+==== Exercițiul 2 - Tiny-Shell on Windows ====
  
 Ne propunem să continuăm implementarea de **Tiny-Shell**. Ne propunem să continuăm implementarea de **Tiny-Shell**.
  
-<note important>​ Compilarea se va realiza din Visual Studio sau din command-prompt-ul de Visual Studio, iar rularea executabilului ''​tiny.exe''​ se va realiza din **Cygwin**. +<note important>​ Compilarea se va realiza din Visual Studio sau din command-prompt-ul de Visual Studio ​(folosind utilitarul ''​nmake''​), iar rularea executabilului ''​./2-tiny.exe''​ se va realiza din **Cygwin**. 
-     ​Pentru a ajunge ​din Cygwin pe Desktop (atenție la folosirea apostrofurilor):<​code bash> +   ​Dacă alegeți compilarea folosind Visual Studio, executabilul se numește ''​2-tiny.exe''​ și se găsește în calea ''​so/​labs/​lab03/​skel/​win/​Debug'';​  
-$ cd 'C:​\Users\Student\Desktop+   * Dacă alegeți compilarea folosind fișierul ''​Makefile'' ​din calea ''​so/​labs/​lab03/​skel/​win/​2-tiny'',​ executabilul se numește ''​tiny.exe''​ și se află în aceași locație ca fișierul ​''​Makefile''​. 
-</​code>​+ 
 </​note>​ </​note>​
  
-=== 2a. Execuția unei comenzi simple ​(0.5p) ​===+=== 2a. Execuția unei comenzi simple ===
  
 Partea de execuție a unei comenzi simple și a variabilelor de mediu este deja implementată. Partea de execuție a unei comenzi simple și a variabilelor de mediu este deja implementată.
  
-Deschideți fișierul tiny.c din subproiectul ​1-tiny. +Deschideți fișierul tiny.c din subproiectul ​2-tiny. 
-Urmăriți în sursă funcția ''​RunSimpleCommand''​. Testați funcționalitatea prin comenzi de tipul: <code bash> ./tiny+Urmăriți în sursă funcția ''​RunSimpleCommand''​. Testați funcționalitatea prin comenzi de tipul: <code bash> ./2-tiny.exe
 > ls -al  > ls -al 
 > exit</​code>​ > exit</​code>​
  
-=== 2b. Redirectare ​(1.5p) ​===+=== 2b. Redirectare ===
 Realizați redirectarea tuturor HANDLE-relor. Realizați redirectarea tuturor HANDLE-relor.
  
Line 977: Line 1030:
   * Urmăriți în cod comentariile cu TODO 1.   * Urmăriți în cod comentariile cu TODO 1.
   * Revedeți secțiunea [[#​mostenirea handle-urilor la createprocess|Moștenirea handle-urilor]].   * Revedeți secțiunea [[#​mostenirea handle-urilor la createprocess|Moștenirea handle-urilor]].
-  * Atenție la metoda de moștenire a handle-relor ​+  * Atenție la metoda de moștenire a handle-relor
  
-Pentru testare puteți folosi comenzile: <code bash> ./​tiny ​+<​spoiler>​ 
 +După un apel [[http://​msdn.microsoft.com/​en-us/​library/​ms682425%28VS.85%29.aspx | CreateProcess]],​ handle-urile din procesul părinte pot fi **moștenite** în procesul copil.  
 + 
 +Pentru ca un handle să poată fi moștenit în procesul creat, trebuie îndeplinite 2 condiții:​ 
 +    * membrul ''​bInheritHandle'',​ al structurii ''​SECURITY_ATTRIBUTES'',​ transmise lui [[http://​msdn.microsoft.com/​en-us/​library/​aa363858%28VS.85%29.aspx | CreateFile]],​ trebuie să fie ''​TRUE''​ 
 +   * parametrul ''​bInheritHandles'',​ al lui [[http://​msdn.microsoft.com/​en-us/​library/​ms682425%28VS.85%29.aspx | CreateProcess]],​ trebuie să fie ''​TRUE''​.  
 +   * atunci când se doreşte moştenierea handler-elor în procesul copil, trebuie să ne asigurăm că acestea sunt valide deorece în procesul copil nu se fac validări suplimentare. Transmiterea unor handlere invalide poate duce la un comportament nedefinit în procesul copil. 
 + 
 +Pentru **redirectarea** handle-urilor standard în procesul copil: 
 +   ​* ​ folosiți membrii ''​hStdInput'',​ ''​hStdOutput'',​ ''​hStdError''​ ai structurii [[http://​msdn.microsoft.com/​en-us/​library/​ms686331(v=VS.85).aspx | STARTUPINFO]],​ transmise lui [[http://​msdn.microsoft.com/​en-us/​library/​ms682425%28VS.85%29.aspx | CreateProcess]] 
 +   * membrul ''​dwFlags''​ al aceleiași structuri trebuie setat la ''​STARTF_USESTDHANDLES''​ 
 +   * dacă se dorește ca anumite handle-uri să rămână implicite, li se poate atribui handle-ul întors de [[http://​msdn.microsoft.com/​en-us/​library/​ms683231(VS.85).aspx | GetStdHandle]]. 
 + 
 +</​spoiler>​ 
 + 
 + 
 +Pentru testare puteți folosi comenzile: <code bash> ./2-tiny.exe 
 > ls -al > out > ls -al > out
 > cat out > cat out
 > exit</​code>​ > exit</​code>​
  
-=== 2c.  Implementarea unei comenzi cu pipe-uri ​(1.5p) ​===+=== 2c.  Implementarea unei comenzi cu pipe-uri ===
  
 Shell-ul vostru trebuie să ofere suport pentru o comandă de forma ' comanda_simpla | comanda_simpla '. Shell-ul vostru trebuie să ofere suport pentru o comandă de forma ' comanda_simpla | comanda_simpla '.
Line 991: Line 1060:
    * Completați funcția ''​PipeCommands''​.    * Completați funcția ''​PipeCommands''​.
    * zeroizaţi structura ''​SECURITY_ATTRIBUTES sa'',​ respectiv structurile ''​PROCESS_INFO pi1, pi2'';​    * zeroizaţi structura ''​SECURITY_ATTRIBUTES sa'',​ respectiv structurile ''​PROCESS_INFO pi1, pi2'';​
-   * **Atenție! ** În procesul părinte, trebuie închise capetele pipe-urilor.+   * **Atenție! ** În procesul părinte, trebuie închise capetele pipe-urilor ​după ce nu mai sunt folosite. 
 +   * **Atenție! ** membrul ''​bInheritHandle''​ al structurii ''​SECURITY_ATTRIBUTES'',​ transmise lui ''​CreatePipe'',​ trebuie să fie ''​TRUE''​.
    * Pentru redirectari,​ folosiți-vă de funcția ''​RedirectHandle''​.    * Pentru redirectari,​ folosiți-vă de funcția ''​RedirectHandle''​.
    * Revedeți secțiunea despre [[#pipe-uri anonime in windows|Pipe-uri anonime în Windows]].    * Revedeți secțiunea despre [[#pipe-uri anonime in windows|Pipe-uri anonime în Windows]].
  
-Pentru testare puteți folosi comenzile: <code bash> ./​tiny ​+Pentru testare puteți folosi comenzile: <code bash> ./2-tiny.exe
 > cat Makefile | grep tiny > cat Makefile | grep tiny
 > exit</​code>​ > exit</​code>​
Line 1016: Line 1086:
    * **Atenție**:​ Dacă ''​ReadFile''​ întoarce FALSE, iar mesajul de eroare (ce întoarce GetLastError()) este ''​ERROR_BROKEN_PIPE'',​ înseamnă că au fost închise toate capetele de scriere.    * **Atenție**:​ Dacă ''​ReadFile''​ întoarce FALSE, iar mesajul de eroare (ce întoarce GetLastError()) este ''​ERROR_BROKEN_PIPE'',​ înseamnă că au fost închise toate capetele de scriere.
  
-== Magic ==+== Magic (Linux) ​==
  
 Intrați în directorul ''​lin/​5-magic''​ și deschideți sursa ''​magic.c''​ Intrați în directorul ''​lin/​5-magic''​ și deschideți sursa ''​magic.c''​
Line 1024: Line 1094:
 Nu sunt permise alte modificări în funcția ''​main''​. Nu sunt permise alte modificări în funcția ''​main''​.
  
 +== Pipe fără nume (Linux) ==
  
-===== Soluții =====+Intrați în directorul ''​lin/​6-pipe''​ și deschideți sursa ''​pipe.c''​ 
 + 
 +Programul este format din două procese, părinte și copil, care comunică prin intermediul unui pipe anonim. Părintele citește de la tastatură șiruri de caractere pe care apoi le pasează copilului printr-un capăt al unui pipe anonim. Copilul citește din celălalt capăt al pipe-ului anonim și afișează în consolă aceleași date. Practic, procesul copil scrie la consolă ce citește părintele de la tastatură. 
 + 
 +Completați scheletul astfel încât să fie îndeplinită funcționalitatea de mai sus.  
 + 
 +Revedeți secțiunea [[#Pipe-uri anonime în Linux|Pipe-uri anonime în Linux]]. 
 + 
 +Testați folosind: 
 +<code bash> ./pipe 
 +> Salut 
 +> portocala 
 +> exit 
 +</​code>​
  
-[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab03-sol.zip | lab03-sol.zip]] 
  
  
so/laboratoare/laborator-03.1551637226.txt.gz · Last modified: 2019/03/03 20:20 by dragos_florin.costea
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0