Solución del Examen de 1ª Convocatoria

Anuncio
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
[Cuestión 1.]Resuelva con una orden UNIX las siguientes tareas:
Apartado a.- Copie todas las rutas de los directorios donde el intérprete de comandos busca los programas ejecutables al
final del fichero rutas.txt situado en el directorio temporal del sistema.
echo $PATH >> /tmp/rutas.txt
Apartado b.- Modifique los permisos del fichero pdatos.txt del directorio precursos de su directorio de usuario de tal forma
que el propietario tenga todos los perm isos sobre él, el grupo sólo lectura y ejecución, y el resto de usuarios, sólo posean
permiso de lectura.
Chmod 754 $HOME/precursos/pdatos.txt
Apartado c.- Mostrar un listado con información sobre los directorios del sistema (a cualquier nivel) cuyo nombre empieza
por “bin” y sólo tienen permiso de lectura para el propietario. El grupo y otros no disponen de permiso de lectura. Los
permisos de escritura y ejecución no nos importan.
ls –lR / | grep “bin[^ ]*$” |grep “^dr..-..-..“
Apartado d.- Copiar el contenido existente, a cualquier nivel, que se encuentra en el directorio padre del directorio actual al
subdirectorio copia que se encuentra en el directorio que indica la variable de entorno BACKUP.
Cp –R .. $BACKUP/copia
Puntuación: 2 ptos.
Tiempo estimado: 10 min.
1
2
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
[Cuestión 2.]Debe implementarse en C un programa denominado ficheros_regulares_ejecutables, que admita
como parámetro la ruta absoluta de un directorio y muestre por pantalla la ruta y el tamaño en bytes de los ficheros regulares
contenidos, a cualquier nivel, en dicho directorio que tengan al menos permiso de ejecución para el propietario.
Si se ejecuta el programa ficheros_regulares_ejecutables sin indicar ningún argumento adicional, se
mostrará el siguiente mensaje:
Uso: ficheros_regulares_ejecutables <directorio>
En la figura 1 aparece un fragmento de un ejemplo de ejecución de este programa:
murillo:/export/home/examen> ./ficheros_regulares_ejecutables /sbin
Directorio = /sbin
Ruta del archivo ejecutable = /sbin/su Tamanno = 23400 bytes
Ruta del archivo ejecutable = /sbin/autopush Tamanno = 219860 bytes
Ruta del archivo ejecutable = /sbin/dhcpagent Tamanno = 522380 bytes
Ruta del archivo ejecutable = /sbin/dhcpinfo Tamanno = 496588 bytes
Ruta del archivo ejecutable = /sbin/fdisk Tamanno = 274800 bytes
Ruta del archivo ejecutable = /sbin/in.mpathd Tamanno = 526872 bytes
Ruta del archivo ejecutable = /sbin/init Tamanno = 554536 bytes
Ruta del archivo ejecutable = /sbin/jsh Tamanno = 308480 bytes
Ruta del archivo ejecutable = /sbin/mount Tamanno = 262396 bytes
Ruta del archivo ejecutable = /sbin/netstrategy Tamanno = 454280 bytes
Ruta del archivo ejecutable = /sbin/rc0 Tamanno = 2792 bytes
Ruta del archivo ejecutable = /sbin/sh Tamanno = 308480 bytes
Ruta del archivo ejecutable = /sbin/bpgetfile Tamanno = 8892 bytes
Ruta del archivo ejecutable = /sbin/setbootdev Tamanno = 266824 bytes
Ruta del archivo ejecutable = /sbin/apboot Tamanno = 65348 bytes
Ruta del archivo ejecutable = /sbin/apcheck Tamanno = 212112 bytes
Figura 1: Fragmento de un ejemplo de ejecución del programa ficheros_regulares_ejecutables.
NOTAS:
− Debe comprobarse que el segundo argumento que se indica en la línea de comandos es un directorio.
− Para determinar si el propietario tiene permiso de ejecución puede emplear la constante S_IXUSR.
− Los errores que se produzcan deberán mostrarse por la salida estándar de error.
− No se puede utilizar la llamada a system.
Puntuación: 2 ptos.
Tiempo estimado: 25 min.
/***********************************************************/
/*********************** ejercicio2.c *********************/
/***********************************************************/
#include
#include
#include
#include
#include
<stdio.h>
<sys/stat.h>
<sys/file.h>
<dirent.h>
<fcntl.h>
#define LONGITUD_MAX 255
void obtener_entradas_directorio (char *);
3
int main(int argc, char* argv[])
{
struct stat atributos;
if (argc != 2)
{
printf("Uso: %s <directorio>\n", argv[0]);
exit (-1);
}
// Obtenemos información del segundo argumento (archivo o directorio)
if (stat(argv[1], &atributos) == -1)
{
perror("Error en stat");
exit (-2);
}
if (atributos.st_mode & S_IFDIR)
{
fprintf(stdout, "Directorio = %s \n", argv[1]);
obtener_entradas_directorio(argv[1]);
}
else
{
fprintf(stdout, "El argumento %s no es un directorio \n", argv[1]);
exit(-3);
}
return 0;
}
void obtener_entradas_directorio (char *directorio)
{
DIR *dirp;
struct dirent *direntp;
struct stat atributos;
int retorno;
char ruta[LONGITUD_MAX];
dirp = opendir (directorio);
if (dirp == NULL)
{
fprintf(stderr,"No se puede acceder al directorio %s\n", directorio);
exit (-4);
}
// Obtenemos la primera entrada del directorio (ED)
direntp = readdir(dirp);
// Mientras haya entradas en el directorio
while (direntp != NULL)
{
// Construimos la ruta
sprintf(ruta, "%s/%s", directorio, direntp->d_name);
// Obtenemos información de la ED actual
retorno = stat(ruta, &atributos);
if (retorno == -1)
{
fprintf(stderr, "Error en stat de %s \n", direntp->d_name);
}
else
{
// Si es un fichero regular y tiene permiso de ejecución, mostramos la
ruta y el tamanno
if (atributos.st_mode & S_IFREG)
//
if (S_ISREG (atributos.st_mode) )
{
if(atributos.st_mode & S_IXUSR)
4
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
fprintf(stdout, "Ruta del archivo ejecutable = %s Tamanno = %d bytes \n",
ruta, atributos.st_size);
}
// Si es un directorio seguimos por el subdirectorio siguiente
else if (S_ISDIR (atributos.st_mode) && strcmp (direntp->d_name,".") != 0 &&
strcmp (direntp->d_name,"..") != 0)
{
obtener_entradas_directorio (ruta);
}
}
// Obtenemos la siguiente ED
direntp = readdir(dirp);
}
closedir(dirp);
}
5
6
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
[Cuestión 3.]Se desea resolver en C, haciendo uso de la librería de semáforos vista en clase, el problema de los
lectores/escritores, teniendo en cuenta los siguientes aspectos de sincronización:
 Existirán varios procesos escritores, cada uno de los cuales realizará como máximo diez escrituras en el fichero
bd.txt; en caso de que exista el fichero, se añadirán por el final. Suponga que transcurre un segundo entre dos
operaciones seguidas de escritura.
 Los lectores accederán concurrentemente a dicho fichero e irán leyendo las líneas de una en una; una vez leída una
línea será borrada.
 No existe relación filial entre los lectores y los escritores.
A continuación, se detallan el resto de consideraciones del ejercicio:
 Los elementos que se escribirán en el fichero tendrán el siguiente formato: “He escrito el elemento <i> (Proceso
Escritor <PID>)”.
 Sólo un proceso, de cualquier tipo, puede estar accediendo al fichero en un determinado instante.
 Se instalará un manejador en el lector, asociado a la señal SIGINT, que será el encargado de destruir el/los
semáforo/s y el fichero.
 Los prototipos de las funciones para el acceso al fichero son los siguientes:
i. void Escribir_Linea (char *fichero, char* cadena).- Añade una línea con la cadena de caracteres al final
del fichero.
ii. void Leer_Linea (char *fichero).- Leerá y eliminará la primera línea del fichero, en caso de no estar vacío.
Por tanto, debe implementar al menos dos programas, uno para para el lector y otro para el escritor. Sobre las funciones
auxiliares, suponga ya definida la función Leer_Linea, por lo que necesitará codificar la función Escribir_Linea y el manejador
asociado a la señal SIGINT.
Puntuación: 3 ptos.
#include
#include
#include
#include
#include
#include
#include
Tiempo estimado: 40 min.
<stdio.h>
<sys/types.h>
<sys/stat.h>
<fcntl.h>
<string.h>
<errno.h>
<signal.h>
#include "Semaph.h"
void Iniciador ();
void Terminador (int sig);
void Escribir_Linea(char *fichero, char* cadena);
Semaph excmut, escritos;
/*************************************************************/
//
lector.c
//
/*************************************************************/
#include "funciones.h"
int main()
{
Iniciador();
if (signal(SIGINT, Terminador)== SIG_ERR)
perror ("Error al instalar el manejador asociado a SIGINT");
while(1)
{
Semaph_Down(escritos);
7
}
}
Semaph_Down(excmut);
fprintf(stdout, "Voy a leer un valor\n");
Leer_Linea("bd.txt");
Semaph_Up(excmut);
/*************************************************************/
//
escritor.c
//
/*************************************************************/
#include "funciones.h"
int main()
{
int i=0;
char cadena[255];
Iniciador();
if (signal(SIGINT, Terminador)== SIG_ERR)
perror ("Error al instalar el manejador asociado a SIGINT");
}
for(i=0;i<10;i++)
{
Semaph_Down(excmut);
sprintf(cadena, "He escrito el elemento %d (Proceso Escritor %ld)\n", i,getpid());
Escribir_Linea("bd.txt", cadena);
Semaph_Up(excmut);
Semaph_Up(escritos);
// Entre dos operaciones de escritura el escritor
// está ocioso un segundo.
sleep(1);
}
/*************************************************************/
//
funciones.c
//
/*************************************************************/
#include "funciones.h"
void Iniciador ()
{
excmut = Semaph_Create("excmut", 1);
if (excmut == -1)
{
perror("Error al crear/acceder semaforo excmut");
exit(-1);
}
}
escritos = Semaph_Create("escritos", 0);
if (escritos == -1)
{
perror("Error al crear/acceder semaforo escritos");
exit(-1);
}
void Terminador (int sig)
{
Semaph_Destroy("excmut", excmut);
Semaph_Destroy("escritos", escritos);
unlink("bd.txt");
}
void Escribir_Linea(char *fichero, char* cadena)
{
int fd;
fd = open("bd.txt", O_CREAT | O_WRONLY | O_APPEND, 0600);
8
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
if (fd == -1)
{
perror("Error en open");
exit(-1);
}
// Escribe la cadena en el fichero
if (write(fd, cadena, strlen(cadena)) == -1)
{
perror("Error en la escritura");
exit(-1);
}
fprintf(stdout, "%s \t escrito en datos.txt\n", cadena);
fprintf(stdout, "--------------------------------------------\n");
}
close(fd);
9
10
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
[Cuestión 4.]Realice un cliente en C que se conecte al puerto 2323 de un servidor que se indicará como primer argumento al
invocar el programa. Además, el cliente tomará los siguientes argumentos como nombres de usuarios que hay que enviar al
servidor en un determinado protocolo para que éste nos diga si existen en el sistema. La información recibida del servidor se
mostrará por pantalla.
NOTAS:
- Si el usuario no pasa a nuestro cliente el número de argumentos adecuados, mostrará un mensaje de uso por pantalla.
- La cadena que se debe enviar al servidor para comprobar si existe el usuario en dicho servidor es: USER usuario,
reemplazando usuario por cada uno de los nombres que se han pasado como argumentos. El servidor contestará con
OK si el usuario existe y con NOK en caso de que el usuario no exista en el servidor. Para terminar, debe enviarse el
mensaje FIN al servidor y éste contestará también con dicho mensaje y se cerrará la conexión.
- Implemente únicamente el cliente
A continuación se muestra un ejemplo del funcionamiento del programa:
$ ./usuarios murillo.eii.us.es juanpe fragu moreno
Envío: USER juanpe
Respuesta: OK
Envío: USER fragu
Respuesta: NOK
Envío: USER moreno
Respuesta: OK
Envío: FIN
Respuesta: FIN
$
Figura 2. Ejemplo de funcionamiento del programa.
Puntuación: 3 ptos.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
Tiempo estimado: 30 min.
<stdio.h>
<stdlib.h>
<sys/socket.h>
<sys/types.h>
<netinet/in.h>
<netdb.h>
<string.h>
<stdio.h>
<arpa/inet.h>
<errno.h>
<sys/wait.h>
<signal.h>
#define LONG_HOSTNAME 100
#define TAM_MENSAJE 100
int main(int argc, char * argv[])
{
int socket_escucha, puerto;
int s;
struct sockaddr_in sin;
struct hostent *hp;
char hostname[LONG_HOSTNAME];
char mensaje[TAM_MENSAJE]="";
char fichero[TAM_MENSAJE];
11
int n_bytes=0,i;
if (argc < 3)
{
fprintf(stderr, "Uso: %s <maquina> <usuario>...\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Almacenamos host */
sscanf(argv[1],"%s", hostname);
n");
/* Obtenemos la direccion IP a partir del nombre */
hp = gethostbyname(hostname);
if (hp == NULL)
{
perror("Error al obtener la direccion IP asociada al nombre de la maquina\
}
exit(EXIT_FAILURE);
/* Creamos el socket de escucha */
if ((s = socket(AF_INET, SOCK_STREAM,0))<0)
{
perror("Error al crear el socket");
exit(EXIT_FAILURE);
}
/* Creamos la direccion a la que enlazar el socket de escucha */
sin.sin_family = AF_INET;
/* Tipo internet */
sin.sin_port = htons(2323);
/* Puerto en Network byte order */
memmove(&sin.sin_addr, hp->h_addr, hp->h_length); /* Obtenemos la direccion IP
de Network byte order */
if (connect(s, (struct sockaddr *) &sin, sizeof(sin))<0)
{
perror("Error al hacer accept");
exit(EXIT_FAILURE);
}
for(i=2;i<argc;i++)
{
sprintf(mensaje,"USER %s", argv[i]);
printf("Envio: %s\n", mensaje);
n_bytes=send(s,mensaje, strlen(mensaje),0);
if (n_bytes < 0)
{
perror("Error en send");
exit(EXIT_FAILURE);
}
n_bytes=recv(s,mensaje, sizeof(mensaje),0);
if (n_bytes > 0)
{
mensaje[n_bytes]='\0';
printf("Respuesta: %s\n", mensaje);
fflush(stdout);
}
else
{
fprintf(stderr,"Error en recv\n");
exit(EXIT_FAILURE);
}
} //for argumentos
sprintf(mensaje,"FIN");
printf("Envio: %s\n", mensaje);
n_bytes=send(s,mensaje, strlen(mensaje),0);
if (n_bytes < 0)
{
perror("Error en send");
exit(EXIT_FAILURE);
12
Examen de Laboratorio de Sistemas Operativos. Primera Convocatoria
Curso 2008/09. Tercero Ingeniería Informática
Nombre:
Apellidos:
17 de Junio de 2009
}
{
n_bytes=recv(s,mensaje, sizeof(mensaje),0);
if (n_bytes > 0)
}
mensaje[n_bytes]='\0';
printf("Respuesta: %s\n", mensaje);
fflush(stdout);
close(s);
} /*main*/
13
Descargar