Está en la página 1de 5

Examen de Laboratorio de Sistemas Operativos. Tercera Convocatoria 2002/03.

Tercero Ingeniera Informtica


Nombre: Apellidos: Grupo: 4 de Diciembre de 2003

[Cuestin 1.] Escriba un programa anillo que cree un anillo de tres procesos conectados por tuberas. El primer proceso deber pedirle al usuario un mensaje por la entrada estndar y envirselo al segundo proceso. El segundo proceso deber invertir la cadena y enviarla al tercer proceso. El tercer proceso deber convertir la cadena a maysculas y envirsela de vuelta al primer proceso. Cuando el primer proceso obtenga la cadena procesada, deber mostrarla por la salida estndar. Cuando esta cadena se termine, los tres procesos debern terminar. La Figura 2 muestra un esquema del anillo de procesos. Y la Figura 1 muestra un ejemplo de una posible ejecucin del programa.
$ anillo Introduzca una cadena: hola Mariola La cadena procesada es: ALOIRAM ALOH $ _

leer stdin / escribir stdout

invertir

convertir a maysculas

Figura 1. Ejemplo de ejecucin del programa anillo. Figura 2. Esquema de procesos del programa anillo. NOTAS: No se pueden dejar procesos hurfanos. Como ayuda se suponen definidas las dos siguientes funciones: o void invertir (char cadena[]); La funcin invertir tiene un parmetro (cadena) de entrada/salida que ser una cadena bien formada. Este argumento deber contener la cadena a invertir, y una vez que invertir haya realizado su tarea, contendr la cadena invertida. o void amayuscula (char cadena[]); La funcin amayuscula tiene un argumento de entrada/salida que tambin deber ser una cadena bien formada. . Este argumento deber contener la cadena que se quiere convertir a maysculas, y una vez que amayuscula haya realizado su tarea, contendr la cadena en maysculas.

Puntuacin: 3 puntos.
#define NUM_TUBS #define MAX 3 255

Tiempo estimado: 30 min.

void cerrartuberias (int tub[NUM_TUBS][2]); void invertir(char cadena[]); void amayuscula(char cadena[]); int main(void){ int t[NUM_TUBS][2]; int i, status; pid_t pid, w; char cadena[MAX];

for (i=0; i< NUM_TUBS; i++) if (pipe(t[i]) < 0) { fprintf(stderr, "Error creando tubera %d\n", i); exit (0); }

for (i=0; i < NUM_TUBS-1; i++)

{ pid = fork();

if (pid == 0) { /* Un hijo */ /* Leer de la tuberia anterior */ if (read(t[i][0], cadena, sizeof(cadena)) <0){ fprintf(stderr, "error leyendo de tuberia %d\n", i); exit(1); } if (i == 0) invertir(cadena); else if (i == 1) amayuscula (cadena); /* Escribimos el resultado en la tuberia siguiente */ write (t[i+1][1], cadena, strlen(cadena)+1); cerrartuberias(t); exit(0); } else if (pid <0){ fprintf (stderr, "Error creando procesos\n"); exit(1); } } /*Leer de la ent. estndar e imprimir por la salida estndar */ /* Hasta que no lanzo los hijos, no me pongo a coger el mensaje para no bloquearme */ gets(cadena); write (t[0][1], cadena, strlen(cadena)+1); if (read (t[2][0], cadena, sizeof(cadena))<0){ fprintf(stderr, "error leyendo de tubera 2\n"); exit(1); } else printf("%s\n", cadena); cerrartuberias(t); /* Espera*/ w = wait(&status); while ( w>0 || (w == -1 && errno == EINTR)) w=wait(&status); } void cerrartuberias (int tub[NUM_TUBS][2]) { int i; for (i=0; i < NUM_TUBS; i++){ close(tub[i][0]); close(tub[i][1]); } }

Examen de Laboratorio de Sistemas Operativos. Tercera Convocatoria 2002/03. Tercero Ingeniera Informtica
Nombre: Apellidos: Grupo: 4 de Diciembre de 2003

[Cuestin 2.] Escriba el cdigo C para la funcin int Down(int semid, int nsem), donde semid es el identificador del grupo de semforos y nsem es el nmero de semforo sobre el que se quiere realizar una operacin Down. Esta funcin devolver -1 en caso de error o 0 en caso contrario.

Puntuacin: 1 punto.
int Down(int semid, int nsem) { int result=0; struct sembuf op_down; op_down.sem_num=nsem; op_down.sem_op=-1; op_down.sem_flg=0; result = semop(semid,&op_down,1); return result; }

Tiempo estimado: 10 min.

[Cuestin 3.] Considrese un escenario con un spooler de impresin con una cola de trabajos de impresin de tamao MAX_JOBS y un conjunto de procesos de usuario con las siguientes restricciones de sincronizacin y comunicacin: I) Los trabajos se identifican por el nombre del archivo que contiene el documento a imprimir. Se dispone de una funcin Imprimir (char *archivo) que se encarga de imprimir el archivo que contiene el trabajo. II) En el caso de que no exista ningn trabajo de impresin pendiente el spooler se echa a dormir, en caso contrario, permanecer despierto. III) Un usuario slo podr mandar a impresin un trabajo job cuando el nmero de trabajos en cola sea menor que MAX_JOBS, en caso contrario, se genera un error y el proceso de usuario termina. Fjese que NO espera a que se libere espacio en la cola de impresin. Haciendo uso de la biblioteca de semforos realizada en el laboratorio, escriba el cdigo C del proceso Spooler y los procesos Usuario. Omita la inclusin de ficheros de cabecera. Considere qu existe una variable compartida llamada jobQ de tipo Queue con las siguientes funciones para su creacin, insercin de trabajos, borrado de trabajos y consulta de tamao, respectivamente: Queue void void void int q; Queue_Create Queue_Add Queue_Remove Queue_Size

(Queue (Queue (Queue (Queue

q, int maxQ); q, char nombreArchivo[]); q, char nombreArchivo[]); q);

Puntuacin: 3 puntos.
Variables compartidas: Semaph mutex; Semaph aviso; Queue jobQ; Iniciador: mutex=Semaph_Create(mutex, 1); aviso=Semaph_Create(aviso,0); Queue_Create(jobQ, MAX_JOBS);

Tiempo estimado: 30 min.

Spooler: char job[MAX]; for(;;) { Semaph_Down(aviso); // Esperar a que existan trabajos que imprimir Semaph_Down(mutex); // Acceso exclusivo a jobQ Queue_Remove(jobQ, job); Semaph_Up(mutex); // Fin del acceso exclusivo Imprimir(job); } Usuario: Semaph_Down(mutex); // Acceso exclusive a jobQ if (Queue_Size(jobQ) < MAX_JOBS) { Queue_Add(jobQ, job); Semaph_Up(mutex); // Fin del acceso exclusivo Semaph_up(aviso); // Aviso de que existe un nuevo trabajo en jobQ } else { Semaph_Up(mutex); // Fin del acceso exclusivo }

[Cuestin 4.] Realizar un programa que busque en un directorio determinado, qu ficheros contienen una cadena dada, y cuntas veces aparece dicha cadena en cada uno de los ficheros. La invocacin sera: $ buscaEnDirectorio <nombreDirectorio> <cadena> Un ejemplo de ejecucin del programa sera el siguiente: murillo:/tmp> En el fichero En el fichero En el fichero En el fichero buscaEnDirectorio prueba char prueba/arbol.e hay 6 apariciones de la cadena 'char' prueba/dic.c~ hay 11 apariciones de la cadena 'char' prueba/dic.c hay 10 apariciones de la cadena 'char' prueba/core hay 2 apariciones de la cadena 'char'

NOTAS: No se permite la utilizacin de la llamada al sistema system() para resolver el ejercicio. Slo es necesario buscar en los ficheros que estn dentro del directorio determinado, no siendo necesario buscar en los subdirectorios de ste. Se supone implementada la funcin int contarApariciones(int fich, char cadena[]), que devuelve el nmero de apariciones de cadena en el fichero cuyo descriptor es fich.

Puntuacin: 2 pto.
#include #include #include #include #include <stdio.h> <sys/file.h> <fcntl.h> <sys/stat.h> <dirent.h>

Tiempo estimado: 20 min.

#define MAXCAR 100 int contarApariciones(int, char *); static char busqueda[MAXCAR]; static int estado; int main(int argc, char* argv[]) { DIR *dirp; struct dirent *direntp; struct stat statbuf; int ap,fd; char fichero[MAXCAR];

Examen de Laboratorio de Sistemas Operativos. Tercera Convocatoria 2002/03. Tercero Ingeniera Informtica
Nombre: Apellidos: Grupo: 4 de Diciembre de 2003

if (argc!=3) { printf("El numero de argumentos de entrada tiene que ser tres\n"); return -1; } dirp = opendir(argv[1]); if(dirp==NULL) { printf("No se ha podido abrir el directorio"); return -1; } while((direntp=readdir(dirp))!=NULL) { sprintf(fichero,"%s/%s",argv[1],direntp->d_name); if(-1==stat(fichero,&statbuf)) { printf("Error al abrir el fichero\n"); exit(2); } if (statbuf.st_mode & S_IFREG) { fd=open(fichero, O_RDONLY); ap=contarApariciones(fd,argv[2]); if(ap>0) printf("En el fichero %s hay %d apariciones de la cadena '%s'\n", fichero, ap, busqueda); close(fd);//cerramos el fichero } }//while closedir(dirp); }

[Cuestin 5.]

Resuelva con una lnea de comandos UNIX los siguientes apartados:

Apartado a .- Un usuario pretende obtener el nmero de ficheros que tiene en su cuenta, a los cuales slo tiene acceso el propietario. Escriba un comando que cuente el nmero de archivos que cumplen esta propiedad.

ls alR $HOME | grep ^\-...\-\-\-\-\-\-| wc -l

Apartado b .- Escribir un comando que guarde en un fichero llamado conexiones.txt, la lista numerada y ordenada por orden alfabtico, de los ltimos 20 usuarios que se han conectado a la mquina desde la que se ejecute el comando. last n 20 | sort |cat n > conexiones.txt

NOTAS: Puede serle de ayuda el comando last visto en clase.

Puntuacin: 1 punto.

Tiempo estimado: 10 min. 5

También podría gustarte