Está en la página 1de 6

Examen Prctico de Sistemas Operativos. Segunda Convocatoria 2002/03.

Tercero Ingeniera Informtica


Nombre: Apellidos: Grupo: 16 de Septiembre de 2003

[Cuestin 1.] Realice un programa chequeacopia que tome como argumentos de entrada dos ficheros o dos directorios, e indique dando un mensaje por la salida estndar: -Para dos directorios, si tienen el mismo nmero de entradas. -Para dos ficheros, si tienen el mismo tamao. En caso de que como argumentos se introduzcan un archivo y un directorio, se dar un mensaje de error. Algunos ejemplos de ejecucin del comando seran los que se muestran a continuacin. $ chequeacopia inicio.c inicio.c Los archivos tienen el mismo tamao: 57 bytes. $ chequeacopia nuevo copia Los directorios tienen el mismo nmero de entradas: 10. $ chequeacopia inicio.c final.c Los archivos NO tienen el mismo tamao. NOTAS: No se permite la utilizacin de la llamada al sistema system() para resolver el ejercicio. Se aconseja que implemente la siguientes funciones para resolver el problema: o void tratar_directorios (char dir1[], char dir2[]); o void tratar_archivos (struct stat f1, struct stat f2); o int contar_entradas (char dir1[]);

Puntuacin: 2.5 ptos.


#include #include #include #include #include <stdio.h> <sys/file.h> <fcntl.h> <sys/stat.h> <dirent.h>

Tiempo estimado: 25 min.

void tratar_directorios(char *,char *); void tratar_archivos (struct stat,struct stat); int main(int argc, char* argv[]) { struct stat statOrg; struct stat statDes; if (argc != 3) { fprintf(stderr, "Usage: %s <fichOrg/dirOrg><fichDes/dirDes>\n", argv[0]); return 1; } /* Obtenemos informacin del archivo o directorio */ if (stat(argv[1], &statOrg) == -1) { perror("Error en stat del Origen"); return 4; } if (stat(argv[2], &statDes) == -1) {

perror("Error en stat del Destino"); return 4; } if ((statOrg.st_mode & S_IFDIR) && (statDes.st_mode & S_IFDIR)) tratar_directorios(argv[1],argv[2]); else { if((statOrg.st_mode & S_IFREG) && (statDes.st_mode & S_IFREG)) tratar_archivos(statOrg, statDes); else fprintf(stderr, "No se pueden comparar un fichero y un directorio\n"); } } void tratar_archivos (struct stat statOrg, struct stat statDes) { if(statOrg.st_size==statDes.st_size) printf ("Los ficheros tienen el mismo tamao: %d\n", statOrg.st_size); else printf("Los ficheros NO tienen el mismo tamao\n"); } void tratar_directorios (char *nombre1, char *nombre2) { int numEntradas1; int numEntradas2; numEntradas1=contar_entradas (nombre1); numEntradas2=contar_entradas (nombre2); if(numEntradas1==numEntradas2) printf("Los directorios tienen el mismo numero de entradas:%d\n", numEntradas1); else printf("Los directorios NO tienen el mismo numero de entradas\n"); } int contar_entradas (char *nombredir) { DIR *dirp; struct dirent *d; struct stat statbuf; int numEntradas=0; dirp = opendir (nombredir); if (dirp == NULL) { fprintf(stderr,"No se puede abrir el directorio %s\n", nombredir); exit (2); } d = readdir(dirp); /* Obtenemos la primera entrada del directorio */ /* Mientras haya entradas en el directorio */ while (d != NULL) { numEntradas=numEntradas + 1; d = readdir(dirp); } closedir(dirpOrg); return (numEntradas); }

Examen Prctico de Sistemas Operativos. Segunda Convocatoria 2002/03. Tercero Ingeniera Informtica
Nombre: Apellidos: Grupo: 16 de Septiembre de 2003

[Cuestin 2.] Escriba el cdigo C para la funcin int Enviar_Mensaje(int cola, Mensaje m), donde cola es el identificador de la cola de mensajes a la que se quiere enviar el mensaje m, que tiene la siguiente estructura: typedef struct{ long mtype; char cabecera[64]; char cuerpo[1024]; }Mensaje; Esta funcin devolver -1 en caso de error o 0 en caso contrario. NOTAS: El mensaje m est creado y contiene todos los campos rellenos con la informacin a enviar.

Puntuacin: 1pto.
int Enviar_Mensaje (int cola, Mensaje m) { int result=0; int size = 0; size = sizeof(m) sizeof (m.mtype); result = msgsnd (cola, &m, size, 0); return result; }

Tiempo estimado: 10 min.

[Cuestin 3.] Se desea implementar una biblioteca de semforos contadores para un sistema operativo que SLO dispone de un compilador de C y de semforos binarios, que slo pueden adoptar los valores cero y uno, con el siguiente interfaz: BSemaph Void void void Se pide: Apartado a.- Declarar un nuevo tipo de datos llamado Semaph para implementar los semforos contadores. Cuntos semforos binarios necesita y por qu? BSemaph_Create(char nombre[], int valor_inicial); BSemaph_Destroy(char nombre[], BSemaph bs); BSemaph_Down(BSemaph bs); BSemaph_Up(Bsemap bs);

Se necesitan tres semforos binarios cmo mnimo: uno para obtener exclusin mutua sobre la variable contador (exc), otro para detener a los procesos que hagan Down cuando el contador haya alcanzado el valor cero (esp) y otro para no permitir que varios procesos puedan ejecutar Down al mismo tiempo y tener que gestionar una lista de procesos bloqueados (blqd). En el caso de querer prescindir de este semforo y optar por gestionar una lista de procesos bloqueados se necesita otro semforo para garantizar el acceso exclusivo a dicha lista.
struct sem_cont { int contador; BSemaph blqd, exc, esp; } typedef struct sem_cont * Semaph;

Apartado b.- Escribir el cdigo C que implemente una funcin constructora que dado un nombre y un valor, cree un nuevo semforo contador con dicho nombre y dicho valor inicial. Semaph Semaph_Create(char nombre[], int valor) { Semaph result; char semaf[LON_NOMBRE]; result = (Semaph) malloc(sizeof(struct sem_cont)); result->contador = valor; sprintf (semaf, %s_blqd, nombre); result->blqd = BSemaph_Create(semaf, 1); sprintf (semaf, %s_exc, nombre); result->exc = BSemaph_Create(semaf, 1); sprintf (semaf, %s_esp, nombre); result->esp = BSemaph_Create(semaf, 0); return result; } Apartado c.- Escribir dos funciones C para implementar las operaciones Up y Down. Semaph_Down(Semaph s) { BSemaph_Down(s->blqd); BSemaph_Down(s->exc); --(s->contador); if (s->contador >= 0) BSemaph_Up(s->exc) else { BSemaph_Up(s->exc); BSemaph_Down(s->esp); } BSemaph_Up(s->blqd); } Semaph_Up(Semaph s) { BSemaph_Down(s->exc); ++(s->contador); if (s->contador <= 0) BSemaph_Up(s->esp); BSemaph_Up(s->exc); }

Puntuacin: 3 ptos.

Tiempo estimado: 30 min.

Examen Prctico de Sistemas Operativos. Segunda Convocatoria 2002/03. Tercero Ingeniera Informtica
Nombre: Apellidos: Grupo: 16 de Septiembre de 2003

[Cuestin 4.] En los sistemas Unix existe un archivo llamado hosts situado en el directorio /etc que contiene una asociacin entre direcciones y nombres de mquinas. Un ejemplo del formato de este archivo se muestra en la Figura 1.
127.0.0.1 localhost 150.214.142.14 murillo 10.1.12.14 murillo-int 150.214.141.104 antena 150.214.142.17 aleixandre 150.214.141.131 casiopea 150.214.142.20 machado 150.214.142.21 cernuda # Aula de Ordenadores 1 10.1.12.75 pc-12-75 10.1.12.76 pc-12-76

loghost mailhost cache www ftp

Se pide escribir un comando que devuelva el nmero de entradas que hay pertenecientes a la subred 150.214.141.

Figura 1. Extracto del archivo /etc/hosts.

Puntuacin: 0,5 ptos.


grep /etc/hosts ^150.214.141 | wc -l

Tiempo estimado: 5 min.

[Cuestin 5.] Se desean sincronizar dos procesos en un sistema que solamente dispone de tuberas como mecanismo de comunicacin/sincronizacin. Se pide realizar un programa catsincro <seg> <archivo> que cree dos procesos. El proceso padre, esperar <seg> segundos transcurridos los cuales avisar al proceso hijo. El hijo, al recibir el aviso, imprimir por la salida estndar byte a byte el contenido de <archivo>. Cuando acabe de realizar esta tarea, avisar al padre, el cual tendr que volver a esperar <seg> segundos para volver a avisar a su hijo. NOTAS: El archivo debe tratarse a bajo nivel.

Puntuacin: 3 ptos.
#include #include #include #include <stdio.h> <unistd.h> <fcntl.h> <sys/types.h>

Tiempo estimado: 30 min.

#define STDOUT_FILENO 1 void avisar (int tub[]); void esperar (int tub[]); void imprimir_archivo (char *archivo); int main(int argc, char *argv[]) { int tubPadre[2]; int tubHijo[2]; pid_t childpid; int segundos; if (argc !=3){ fprintf(stderr, "Usage: %s <segundos> <archivo>\n", argv[0]); exit(1); } sscanf(argv[1], "%d", &segundos);

if (pipe (tubPadre) <0 || pipe (tubHijo) < 0){ fprintf(stderr, "Error creando tuberas\n"); exit(1); } childpid=fork(); if (childpid < 0){ fprintf(stderr, "Error creando procesos\n"); exit(1); } else if (childpid == 0){ /* Proceso hijo */ while (1){ esperar(tubHijo); imprimir_archivo(argv[2]); avisar(tubPadre); } } else { /* Proceso padre */ while (1){ sleep(segundos); avisar(tubHijo); esperar(tubPadre); } } } void avisar(int tuberia[2]) { if (write (tuberia[1], "c", 1) <0 ){ fprintf (stderr,"Error escriendo en tuberia\n"); exit(1); } } void esperar (int tuberia[2]) { char c; if (read(tuberia[0],&c, 1) != 1){ fprintf (stderr, "Error leyendo de tuberia\n"); exit(1); } } void imprimir_archivo(char archivo[]) { int fd; char c; int leidos; fd = open (archivo, O_RDONLY); if (fd <0){ fprintf (stderr, "Error abriendo archivo\n"); exit(0); } leidos = read (fd, &c, sizeof(c)); while (leidos > 0){ write (STDOUT_FILENO, &c, sizeof(c)); leidos = read (fd, &c, sizeof(c)); } close (fd); fflush(stdout); }

También podría gustarte