Está en la página 1de 7

Memoria Práctica 2.

Sistemas Operativos
2021-2022
Carlos Jiménez López e Iván Gutiérrez Aguilera
Índice:

- Ser capaz de reconocer y ejecutar en foreground líneas con un solo mandato y 0 o


más argumentos.
- Ser capaz de reconocer y ejecutar en foreground líneas con un solo mandato y 0 o
más argumentos, redirección de entrada estándar desde archivo y redirección de
salida a archivo.
- Ser capaz de reconocer y ejecutar en foreground líneas con más de dos mandatos
con sus respectivos argumentos, enlazados con’|’, redirección de entrada estándar
desde archivo y redirección de salida a archivo.
- Ser capaz de ejecutar el mandato cd (0.5 puntos). Mientras que la mayoría de los
mandatos son programas del sistema, cd es un mandato interno que debe ofrecer el
propio intérprete de mandatos. El mandato cd debe permitir tanto el acceso a través
de rutas absolutas como relativas, además de la posibilidad de acceder al directorio
especificado en la variable HOME si no recibe ningún argumento, escribiendo la ruta
absoluta del nuevo directorio actual de trabajo. Para el correcto cambio de
directorio el comando cd se debe ejecutar sin pipes.
- Evitar que los comandos lanzados en background y el minishell mueran al enviar las
señales desde el teclado SIGINT y SIGQUIT, mientras los procesos en foreground
respondan ante ellas.
- Cambios realizados para la evaluación extraordinaria.
- Ser capaz de reconocer y ejecutar en foreground líneas con un solo mandato y 0 o
más argumentos.

Se abre un proceso hijo que ejecute el mandato recibido, para ello primero comprobamos si el
propio mandato es un cd, para ejecutarlo como se explicará en apartados posteriores. Si no lo
es, podemos ejecutarlo con la línea execv, pasando el nombre del mandato con filename y sus
argumentos. Si la ejecución es errónea, llegara a las líneas inmediatamente posteriores,
mostrando el error por pantalla y saliendo del programa. Una vez creado el proceso hijo, por
otro lado, el padre esperará mediante wait, status y las señales que nos manda si el hijo
termina y de que modo.

- Ser capaz de reconocer y ejecutar en foreground líneas con un solo mandato y 0 o


más argumentos, redirección de entrada estándar desde archivo y redirección de
salida a archivo.
Para las redirecciones, creamos un entero de valor inicial 0 al que llamamos fallo y un char que
contenga el nombre del fichero o error que se redirecciona. El entero creado nos servirá para
pasarle el valor que produce el comando open, al cual le pasamos nuestro nombre y los
derechos. Si fallo vale -1, significa que se habrá producido algún error al abrir el fichero. En
caos contrario, mediante dup2, cambiamos su dirección actual, entrada estándar, salida o
error estándar por el fichero indicado.

- Ser capaz de reconocer y ejecutar en foreground líneas con más de dos mandatos
con sus respectivos argumentos, enlazados con’|’, redirección de entrada estándar
desde archivo y redirección de salida a archivo.

Para comenzar el apartado y una vez habiendo comprobado que el número de


argumentos introducidos por el usuario es mayor que 1, mediante malloc como se
explica en el enunciado de la practica creamos un bloque de espacio en memoria para
nuestras pipes, que no dejan de ser arrays, y posteriormente reservamos la memoria
de cada uno de estos con un bucle for que recorre todos los que se emplearan en la
línea introducida.
A continuación, con otro bucle for comienza la creación de hijos, en la que tendremos
que dividir según los posibles tres casos, primer hijo, ultimo hijo, e hijos intermedios.
Esto se debe a que el comportamiento de los pipes que empleamos es diferente en
cada uno de ellos. Nos vamos a ayudar del mandato dup2 para redirigir las salidas y
entradas de modo que cada mandato cuente con la ejecución anterior.
En el primer caso, HIJO 1, cerramos las tuberías que no necesitamos, en este caso la de
lectura de la tubería numero 0(la primera), y con el dup2 obligamos a que a la hora de
le ejecución, aquello que se fuese a mostrar por la salida estándar, sea redirigido a la
parte de escritura de la pipe 0. En el caso de los hijos intermedios, cerramos las
tuberías que no necesitamos de igual manera, es decir la de escritura del hijo que nos
pasa la salida almacenada hasta ahora y la de lectura de la tubería actual.
Seguidamente redirigimos de forma similar al apartado anterior la entrada estándar a
nuestra pipe de lectura anterior , la salida del mandato actual en ejecución pasa de
escribirse por terminal a la pipe i y ejecutamos.
En el ultimo caso, el ultimo hijo, no nos hace falta redirigir ninguna escritura, ya que
ahora si el resultado final se escribirá por salida estándar, pero si debemos hacerlo con
la lectura, ya que no debe leer el mandato entregado por pantalla si no el conjunto
almacenado hasta ahora. Finalmente ejecuta.
Para acabar el apartado y como se pide en el enunciado de la práctica, una vez
ejecutado toda la línea correctamente, se liberan las pipes usadas durante el proceso
con ayuda del comando free y un bucle for que las recorra.

- Ser capaz de ejecutar el mandato cd (0.5 puntos). Mientras que la mayoría de los
mandatos son programas del sistema, cd es un mandato interno que debe ofrecer el
propio intérprete de mandatos. El mandato cd debe permitir tanto el acceso a través
de rutas absolutas como relativas, además de la posibilidad de acceder al directorio
especificado en la variable HOME si no recibe ningún argumento, escribiendo la ruta
absoluta del nuevo directorio actual de trabajo. Para el correcto cambio de
directorio el comando cd se debe ejecutar sin pipes.
Antes que nada, declaramos una variable char que apunta al nuevo directorio al que
queremos hacer el cd.
Para poder hace el cd de manera correcta lo primero que hacemos es filtrar
dependiendo del número de argumentos. Si solo es un argumento, eso significa que
solo es el cd, por tanto, queremos ir a HOME, asique con getenv obtenemos la
dirección de HOME y se la igualamos a nuestra variable nuevodir. Luego comprobamos
si HOME existe o no. Si el numero de argumento es 2, eso quiere decir que el cd tiene
un directorio, asique lo igualamos. De esta forma si el numero de argumentos es
distinto de estos dos, se está intentando hacer un cd a más de un directorio cosa que
es imposible.
Después de este filtro, con chdir hacemos un cd a lo que había dentro del nuevodir, es
decir, lo ejecutamos.
Para terminar, comprobamos si se ha ejecutado bien.
- Evitar que los comandos lanzados en background y el minishell mueran al enviar las
señales desde el teclado SIGINT y SIGQUIT, mientras los procesos en foreground
respondan ante ellas.
Nada más empezar el programa, hacemos que se ignoren las señales SIGINT Y SIGQUIT
por defecto con la llamada SIG_IGN, para que no se pueda hacer Ctrl+C ni Ctrl+\.
Una vez entrado en la ejecución de los mandatos, lo volvemos a activar con la llamada
SIG_DFL

- Evaluación extraordinaria.
Los principales errores que se apreciaban en la práctica eran dos. El primero es acerca
de las redirecciones, ya que una vez se realizaba una de estas, la Shell no volvía a
escribir o leer de la salida estándar. Es por ello que tuvimos que añadir al final del
while, antes de que comenzase el bucle para el siguiente mandato o línea de
mandatos, que se restableciesen las salidas y entradas estándar con dup2. Para ello
previamente debemos guardar dichas salidas y entradas.
El segundo problema era acerca de las señales, las cuales desactivamos en el sitio
incorrecto, es por eso que ahora se encuentran desactivadas en todo lugar menos en
aquellos en los que se esta llevando a cabo un proceso hijo, es decir, la ejecución de un
mandato.

También podría gustarte