Laboratorio No 3

Proyecto No1

Construyendo una Shell Unix

 

Fecha de inicio: Lunes, 26 de marzo, 2006

Fecha de entrega: Lunes, 2 de abril, 2006

 

Objetivos

 

-          Fomentar en los estudiantes el desarrollo de habilidades en programación en C o C++

-          Introducir a los estudiantes en el manejo de procesos concurrentes en Unix, creación, ejecución y terminación usando llamadas a sistemas fork(), exec() y wait()

-          Desarrollar habilidades simples con control y comunicación de procesos concurrentes usando señales.

-          Desarrollar habilidades simples con comunicación entre procesos usando pipes

 

 

Metodología

 

Trabajo en grupo de 2 personas. Al final de la primera sesión los grupos deberán enviar su código para evaluar el avance del proyecto. En la siguiente sesión se realizará la revisión del proyecto.

 

Descripción

 

En este laboratorio los estudiantes desarrollarán un intérprete de comandos simple en Unix (shell). La shell a implementar será similar a las disponibles para Unix. La shell que  usted implementará constará de dos partes de implementación y una de prueba y análisis.

 

Parte 1 – Comandos simples

 

La shell debe proporcionar un prompt, lo que identifica el modo de espera de comandos de la shell. Luego, debe leer un comando desde teclado y parsear la entrada para identificar el comando y sus argumentos. Finalmente debe ejecutar el comando ingresado en un proceso concurrente, para lo cual debe usar el llamado a sistema fork() y algunas de las variantes de exec(). Los comandos a soportar son ejecutados en foreground, es decir, la shell ejecuta y espera por el término de su ejecución antes de imprimir el promtp para esperar por el siguiente comando. La correcta implementación de esta etapa lo hace merecedor de un 30% de la nota.

Nota: Si se presiona <enter> sin previo comando, la shell simplemente imprime nuevamente el prompt.

 

 

 

Ejemplo

 

shellABC$> ls -l

total 116

-rwxr-xr-x  1 chernand profes 12299 2006-03-17 10:44 alarma

-rw-r--r--  1 chernand profes   855 2006-03-17 10:44 alarma.c

-rwxr-xr-x  1 chernand profes 13084 2006-03-17 10:35 sigcomm

-rw-r--r--  1 chernand profes  1733 2006-03-17 10:35 sigcomm.c

-rwxr-xr-x  1 chernand profes 11980 2006-03-17 10:26 sigerror

-rw-r--r--  1 chernand profes   354 2006-03-17 10:26 sigerror.c

-rwxr-xr-x  1 chernand profes 12166 2006-03-17 10:30 sigfault

-rw-r--r--  1 chernand profes   496 2006-03-17 10:30 sigfault.c

-rw-r--r--  1 chernand profes  1019 2006-03-17 09:58 sigplan2.c

-rwxr-xr-x  1 chernand profes 11990 2006-03-17 10:40 sigusuario

-rw-r--r--  1 chernand profes   528 2006-03-17 10:40 sigusuario.c

shellABC$>

 

Parte 2 – Comandos background

 

Agregar a la shell soporte para comandos en background, comandos que se ejecutan asincrónicamente, es decir la shell empieza a ejecutar comando, pero no espera por su término e imprime el prompt para ejecutar el siguiente comando. Los comandos background se reconocen porque terminan con un “&”. La implementación debe velar por el uso correcto de las llamadas a sistema wait() y sigaction() para que el proceso padre en la shell reciba las señales de término de los comandos en background. Cuando un proceso en background termina la shell debe imprimir “comando xxx terminó”. En particular, la implementación de su shell deber considerar que el usuario puede finalizar la shell con el comando exit, pero sólo lo puede realizar si no tiene procesos en background ejecutándose. La correcta implementación de esta etapa lo hace merecedor de un 30 % de la nota.

 

Ejemplo

 

shellABC$> sleep 10 &

[1] 23831

shellABC$>

 

Parte 3 - Filtros

 

Agregar a la shell soporte de filtros simples usando pipes. Para su implementación utilice los llamados a sistema pipe() y dup2() para crear un pipe y redirigir la salida y entrada estándar. La correcta implementación de esta etapa lo hace merecedor de un 30% de la nota.

 

 

 

Ejemplo

 

shellABC$> ls –l | grep “lab”

 

Análisis

 

Pruebe su shell con una serie de comandos de Unix, analice los casos en los cuales los comandos no son correctamente ejecutados. Escriba en una o dos páginas los resultados de su análisis, incluyendo los comandos y razones por las cuales su shell no es exitosa. Un correcto análisis lo hace merecedor de un 10% de la nota.

 

 

Un ejemplo de programa usando fork, exec, waitpid se encuentra disponible aquí.

 

Algunas Pistas

 

-          Use el llamado a sistema waitpid(), en lugar de wait(). waitpid() le permite al proceso padre esperar por un hijo específico en forma sincrónica o bien esperar por cualquiera de sus hijos asincrónicamente. Para el segundo caso use la opción WNOHANG y -1 en el parámetro de pid del hijo. Para mayor información vea el manual en línea

-          Para hacer el parsing del comando y sus argumentos puede usar alguna(s) de las siguientes index(), rindex(), strspn(), strcspn(), strtok().

-          Use sigaction y señal SIGCHLD. Si tiene algún problema con un error de “Interrumpted System Call” use el flag SA_RESTART, en la estructura sigaction que defina. Vea el manual en línea de sigaction para mayor información.

-          Si piensa usar C++, piense en map<key, value> para almacenar los comandos background