ANNEX 2 Crides al Sistema: Exemple d’execució de la comanda EXECL. Simulació de la comanda find mitjançant un programa a on s’entra com argument el nom del fitxer a trobar. En cas de que el nombre d’argument sigui incorrecte dóna error. //EXERCICI EXECUCIO ASINCRONA PER PROGRAMA //Execucio d'una comanda en background //Equivalent a find . -name nom_fitxer #include #include #include #include <stdio.h> <sys/file.h> <stdlib.h> <fcntl.h> void main(int argc,char *argv[]) { int pid; if (argc==2) { switch(pid=fork()) { case -1:perror("Fork: Error fatal"); exit(1); case 0: execl("/usr/bin/find","find",".","name",argv[1],(char *)0);//Executem la comanda perror("Execl: Error fatal"); exit(1); } } else { printf("Error: Numero de parametres icorrecte\n"); printf("Us: back fitxer_a_trobar\n"); } } Exemple de la comanda EXECL i CHDIR. Canvia el directori actual del programa i fa un ls del mateix. Com argument s’introdueix el nom del directori a on es vol accedir. #include <stdio.h> #include <sys/file.h> #include <stdlib.h> void main(int argc,char *argv[]) { if (argc==2) { chdir(argv[1]); execl("/bin/ls","ls",(char *)0); } else { printf("Error: Numero de parametres incorrecte\n"); printf("Us: camdir ruta_direcori\n"); } } Exemple d’utilització de un Pipe en el que dos processos es comuniquen a través d’ella. //CRIDES AL SISTEMA: Creacio de pipes entre processos parents //Pipe entre dos fills del mateix pare #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include <sys/file.h> #include <signal.h> #include <stdlib.h> #include <fcntl.h> void main() { int pfd; int pid1,pid2; char s[40]; // fd de la pipe // PID's dels processos fills // Informacio a passar if (mknod("./pipenom1",S_IFIFO|0600,0)!=0) printf("ERROR AL CREAR PIPE"); pfd=open("./pipenom1",O_RDWR,0); switch(pid1=fork()) // Creacio del primer fill { case -1: //Cas d'Error en crear Fill 1 printf("Error en el fork fill 1"); exit(0); case 0: //Codi Fill 1 printf("Fill1: Enviant paraula..."); close(1); //Tanquem sortida standard dup(pfd); //Posem escritura pipe a la ent. st. close(pfd); //Tanquem la escriptura de la pipe write(1,"HOLA",40); //Escriu per la sor.est. HOLA exit(0); //Mor default: //Codi Pare switch(pid2=fork()) { case -1: //Cas d'Error en crear Fill 2 printf("Error en el fork fill 2\n"); exit(0); case 0: //Codi Fill 2 close(0);//Tanquem l'entrada standard dup(pfd); //Posem lec. pipe a la sor. st. close(pfd); //Tanquem la lectura de la pipe read(0,s,40);//Llegeix de la sor. estandard printf("Fill 2: Llegit :%s\n",s); exit(0); //Mor default: //Codi Pare close(pfd); //Tanca file descriptors pipe } } wait(0); //Espera la mort dels dos fills wait(0); unlink("./pipenom1"); } Exemple de la utilització de la crida FORK Un procés pare crea un procés fill i espera a que el procés fill acabi l’execució per acabar. El procés fill realitza una espera Wait( 10) abans d’acabar la seva excució. // CRIDES AL SISTEMA. Exercici senzill sobre FORKS (processos pares i fills) #include <stdio.h> #include <unistd.h> void main() { int pid,pid2; long a; printf("\nCRIDES AL SISTEMA. Exercici sobre FORKS\n"); printf("Creacio d'un proces fill\n"); switch(pid=fork()) // Creacio del fill { case -1:// Cas erroni perror("Error en crear el fill!!!!\n"); exit(0); case 0: // Codi proces fill sleep(10); // El fill dorm una estona printf("\nEl fill ha acabat!!!!\n"); exit(0); default:// Codi proces pare printf("Esperant mort fill de PID=%d\n",pid); pid2=wait(0); // Esperem que mori el fill printf("Ha mort un proces fill de PID=%d\n",pid2); printf("\nEl pare ha acabat!!!!\n"); } } Exemple de comunicació entre processos amb parentiu mitjançant la utilització d’una pipe. El procés pare crea dos procesos fills. Un dels processos fill escriu a través de la pipe un missatge i l’altre procés fill llegeix el missatge. El procés pare espera a que els dos processos fills hagin mort per morir ell. //CRIDES AL SISTEMA: Creacio de pipes entre processos parents //Pipe entre dos fills del mateix pare #include <stdio.h> #include <sys/file.h> #include <unistd.h> void main() { int pfd[2]; int pid1,pid2; char s[40]; // fd de la pipe // PID's dels processos fills // Informacio a passar if (pipe(pfd)<0) // Creacio de la pipe { perror("Error en la pipe"); exit(1); } switch(pid1=fork()) // Creacio del primer fill { case -1://Cas d'Error en crear Fill 1 perror("Error en el fork fill 1"); exit(1); case 0: //Codi Fill 1 printf("Fill1: Enviant paraula..."); close(pfd[0]); //Tanquen la lectura de la pipe close(1); //Tanquem entrada standard dup(pfd[1]); //Posem escritura pipe a la ent. st. close(pfd[1]); //Tanquem la escriptura de la pipe printf("HOLA"); //Escriu per l'entrada estandard HOLA exit(1); //Mor default: //Codi Pare switch(pid2=fork()) { case -1://Cas d'Error en crear Fill 2 perror("Error en el fork fill 2"); exit(1); case 0: //Codi Fill 2 close(pfd[1]); //Tanquem la escriptura pipe close(0); //Tanquem sortida standard dup(pfd[0]); //Posem lectura pipe a la sor. st. close(pfd[0]); //Tanquem la lectura de la pipe sleep(10); //Dorm una estona gets(s); //Llegeix de la sortida estandard printf("Fill 2: Llegit :%s\n",s); exit(1); //Mor default://Codi Pare close(pfd[0]); //Tanca file descriptors de la pipe close(pfd[1]); } } wait(1); wait(1); } //Espera la mort dels dos fills Comunicació entre un pare i un fill a través d’una pipe. Creacio de pipes entre processos parents. El fill redirecciona la sortida estàndard l’entrada de la pipe i el pare redirecciona l’entrada estàndard a la sortida de la pipe. //Pipe entre pare i fill #include <stdio.h> #include <sys/file.h> #include <unistd.h> void main() { int pfd[2]; int pid1,pid2; char s[40]; if (pipe(pfd)<0) {perror("Error en la pipe");exit(1);} switch(pid1=fork()) { case -1:perror("Error en el fork fill 1");exit(1); case 0: close(pfd[0]);//Tanquen la lectura de la pipe close(1); //Tanquem entrada standard dup(pfd[1]); //Posem escritura pipe a la ent. st. close(pfd[1]); //Tanquem la escriptura de la pipe printf("HOLA"); exit(1); default:close(pfd[1]);//Tanquem la escriptura pipe close(0); //Tanquem sortida standard dup(pfd[0]); //Posem lectura pipe a la sor. st. close(pfd[0]); //Tanquem la lectura de la pipe sleep(10); gets(s); printf("%s\n",s); } wait(1); } Simulació de la comanda de shell Simularem la comanda: “who | grep parametre” fent servir dos processos un pel who i un altre pel grep comunicant-se a través d’una pipe per passar-se la informació. Utilitza la comanda execl per executar les comandes. #include #include #include #include void { int int int <stdio.h> <sys/file.h> <stdlib.h> <fcntl.h> main(int argc,char *argv[]) pid1,pid2; pfd[2]; status; if (argc==2) { if (pipe(pfd)<0) {perror("Pipe: Error fatal");exit(1);} //Creacio de la pipe de comunicacio switch(pid1=fork()) { case -1:perror("Fork: Error fatal en Fill 1"); exit(1); case 0: close(pfd[0]); //Tanquem el fd de lectura de la pipe close(1); //Tanquem la sortida estandard dup(pfd[1]); //Posem com a sortida el fd d'escriptura de la pipe close(pfd[1]); //Tanquem el fd d'escriptura de la pipe execl("/usr/bin/who","who",(char *)0); //Executem la comanda perror("Execl: Error fatal"); exit(1); default:switch(pid2=fork()) { case -1:perror("Fork: Error fatal en Fill 2"); exit(1); case 0: close(pfd[1]); //Tanquem el fd d'escriptura de la pipe close(0); //Tanquem l'entrada estandard dup(pfd[0]); //Posem com a entrada el fd de lectura de la pipe close(pfd[0]); //Tanquem el fd de lectura de la pipe execl("/usr/bin/grep","grep",argv[1],(char *)0);//Executem la comanda perror("Execl: Error fatal"); exit(1); default: close(pfd[0]); //Tanquem els dos canals de la pipe close(pfd[1]); } } wait(&status); wait(&status); } else { printf("Error: Numero de parametres incorrecte\n"); printf("Us: pipes2 nom_usuari\n"); } }