practica posix

20
Práctica3: Programación POSIX Programación y Administración de Sistemas 2011-2012 Javier Sánchez Monedero [email protected] 2 o curso de Grado en Ingeniería Informática Departamento de Informática y Análisis Numérico Escuela Politécnica Superior Universidad de Córdoba 26 de octubre de 2012 Resumen Entre otras cosas, el estándar POSIX define una serie de funciones (comportamiento, parámetros y valores devueltos) que deben proporcionar todos los sistemas operativos que quieran satisfacer el estándar. De esta forma, si una aplicación hace un buen uso de estas funciones deberá compilar y ejecutarse sin problemas en cualquier sistema operativo POSIX. En esta práctica vamos a conocer qué es el estándar POSIX, y una implementa- ción de la biblioteca C de POSIX, la biblioteca libre GNU C Library o glibc. En Moodle se adjunta el fichero pas-practica3.tgz que contiene código de ejemplo de las funcio- nes que iremos viendo en clase. Índice 1. Introducción a POSIX 2 2. Objetivos 4 3. Entrega de prácticas 4 4. Documentación de POSIX y las bibliotecas 4 5. Procesado de línea de comandos tipo POSIX 4 5.1. Introducción y documentación ........................... 4 5.2. Ejercicios ........................................ 5 6. Variables de entorno 5 6.1. Introducción y documentación ........................... 5 6.2. Ejercicios ........................................ 6 1

Upload: lichtblick

Post on 16-Nov-2015

30 views

Category:

Documents


3 download

DESCRIPTION

posix

TRANSCRIPT

  • Prctica3: Programacin POSIXProgramacin y Administracin de Sistemas

    2011-2012

    Javier Snchez [email protected]

    2o curso de Grado en Ingeniera InformticaDepartamento de Informtica y Anlisis Numrico

    Escuela Politcnica SuperiorUniversidad de Crdoba

    26 de octubre de 2012

    ResumenEntre otras cosas, el estndar POSIX define una serie de funciones (comportamiento,

    parmetros y valores devueltos) que deben proporcionar todos los sistemas operativosque quieran satisfacer el estndar. De esta forma, si una aplicacin hace un buen uso deestas funciones deber compilar y ejecutarse sin problemas en cualquier sistema operativoPOSIX. En esta prctica vamos a conocer qu es el estndar POSIX, y una implementa-cin de la biblioteca C de POSIX, la biblioteca libre GNU C Library o glibc. En Moodle seadjunta el fichero pas-practica3.tgz que contiene cdigo de ejemplo de las funcio-nes que iremos viendo en clase.

    ndice

    1. Introduccin a POSIX 2

    2. Objetivos 4

    3. Entrega de prcticas 4

    4. Documentacin de POSIX y las bibliotecas 4

    5. Procesado de lnea de comandos tipo POSIX 45.1. Introduccin y documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 45.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

    6. Variables de entorno 56.1. Introduccin y documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 56.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    1

    [email protected]

  • 2 Programacin y Administracin de Sistemas 2011-2012

    7. Obtencin de informacin de un usuario/a 67.1. Introduccin y documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 67.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    8. Ejercicio resumen 1 (0.5 punto) 7

    9. Creacin de procesos Fork y Exec 79.1. Introduccin y documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 79.2. Ejercicios y ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

    10. Seales entre procesos 1110.1. Introduccin y documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . . 1110.2. Ejercicios y ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    11. sockets POSIX 1211.1. Introduccin y conceptos bsicos . . . . . . . . . . . . . . . . . . . . . . . . . . 1211.2. Algoritmo bsico Cliente-Servidor . . . . . . . . . . . . . . . . . . . . . . . . . 1311.3. Pasos de programacin C en el lado Servidor . . . . . . . . . . . . . . . . . . . 1411.4. Pasos de programacin C en el lado Cliente . . . . . . . . . . . . . . . . . . . . 14

    12. Todo junto: un servidor web bsico en C 1512.1. Introduccin y cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1512.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

    13. Ejercicio resumen 2 (1 punto) 17

    14. Trabajo futuro 18

    Referencias 18

    1. Introduccin a POSIX

    Figura 1: Mascota delproyecto GNU (http://www.gnu.org/)

    POSIX es el acrnimo de Portable Operating System Interface; la Xviene de UNIX como sea de identidad de la API (Application Pro-gramming Interface, interfaz de programacin de aplicaciones). Son unafamilia de estndares de llamadas al sistema operativo definidospor el IEEE (Institute of Electrical and Electronics Engineers, Institutode Ingenieros Elctricos y Electrnicos) y especificados formalmenteen el IEEE 1003. Persiguen generalizar las interfaces de los sistemasoperativos para que una misma aplicacin pueda ejecutarse en dis-tintas plataformas. Estos estndares surgieron de un proyecto denormalizacin de las API y describen un conjunto de interfaces deaplicacin adaptables a una gran variedad de implementaciones desistemas operativos [1]. La ltima versin de la especificacin POSIX es del ao 2008, se cono-ce por POSIX.1-2008, IEEE Std 1003.1-2008 y por The Open Group Technical StandardBase Specifications, Issue 7[2].

    http://www.gnu.org/http://www.gnu.org/

  • 1. Introduccin a POSIX 3

    Figura 2: Dennis MacAlistair Ritchie. Colabor en el diseo y desarrollo de los sistemasoperativos Multics y Unix, as como el desarrollo de varios lenguajes de programacin comoel C, tema sobre el cual escribi un clebre clsico de las ciencias de la computacin junto aBrian Wilson Kernighan: El lenguaje de programacin C [4].

    GNU C Library, comnmente conocida como glibc es la biblioteca estndar de lenguajeC de GNU. Se distribuye bajo los trminos de la licencia GNU LGPL. Esta biblioteca siguetodos los estndares ms relevantes como ISO C99 y POSIX.1-2008 [3]. gnulib, tambinconocida como Biblioteca de portabilidad de GNU es una coleccin de subrutinas disea-das para usarse en distintos sistemas operativos y arquitecturas. El objetivo de esta segundabiblioteca es facilitar el desarrollo multi-plataforma de aplicaciones de software libre.

    Figura 3: GNU + Linux = GNU/Linux

    En los sistemas en los que se usan, estasbibliotecas de C proporcionan y definen lasllamadas al sistema y otras funciones bsi-cas, y son utilizadas por casi todos los pro-gramas. Sobre todo, es muy usada en los sis-temas GNU y en el kernel de Linux. Cuan-do hablamos de Linux como sistema opera-tivo completo debemos referirnos a l comoGNU/Linux para reconocer que el siste-

    ma lo compone tanto el ncleo Linux como las bibliotecas de C y otras herramientas deGNU que hacen posible Linux1.

    glibc y gnulib son muy portables y soportan gran cantidad de plataformas de hardwa-re [5]. En los sistemas Linux se instalan normalmente con el nombre de libc6 y gnulibrespectivamente. No debe confundirse con GLib2, otra biblioteca que proporciona estruc-turas de datos avanzadas como rboles, listas enlazadas, tablas hash, etc. y un entorno deorientacin a objetos en C.

    En estas prcticas utilizaremos la biblioteca glibc como implementacin de programa-

    1http://es.wikipedia.org/wiki/Controversia_por_la_denominaci%C3%B3n_GNU/Linux2http://library.gnome.org/devel/glib/

    http://es.wikipedia.org/wiki/Controversia_por_la_denominaci%C3%B3n_GNU/Linuxhttp://library.gnome.org/devel/glib/

  • 4 Programacin y Administracin de Sistemas 2011-2012

    cin del API POSIX. Algunas distribuciones de GNU/Linux, como Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3, pero a efectos de programacin no debera ha-ber diferencias.

    2. Objetivos

    Conocer algunas rutinas POSIX y su implementacin glibc.

    Aprender a utilizar bibliotecas externas en nuestros programas.

    Aprender cmo funcionan internamente algunas partes de GNU/Linux.

    Mejorar la programacin viendo ejemplos hechos por los desarrolladores de las biblio-tecas.

    Aprender a comunicar aplicaciones en red y conocer brevemente la arquitectura Cliente-Servidor.

    3. Entrega de prcticas

    Se pedir la entrega y defensa de algunos ejercicios resmenes que integren varios de losconceptos y funciones estudiadas en clase. Las prcticas deben realizarse a nivel individualy se utilizarn mecanismos para comprobar que se han realizado y entendido.

    4. Documentacin de POSIX y las bibliotecas

    Documentacin POSIX.1-2008: Especificacin del estndar POSIX. Dependiendo de la par-te que documente es ms o menos pedaggica4.

    Documentacin GNU C Library: Esta documentacin incluye muchos de los conceptos queya habis trabajado en asignaturas de introduccin a la programacin o de sistemasoperativos. Es una gua completa de programacin en el lenguaje C, pero sobre to-do incluye muchas funciones que son esenciales para programar, tiles para ahorrartiempo trabajando o para garantizar la portabilidad del cdigo entre sistemas POSIX5.

    5. Procesado de lnea de comandos tipo POSIX

    5.1. Introduccin y documentacin

    Los parmetros que procesa un programa en sistemas POSIX deben seguir un estndarde formato y respuesta esperada6. Un resumen de lo definido en el estndar es lo siguiente:

    3http://www.eglibc.org/home4http://pubs.opengroup.org/onlinepubs/9699919799/5http://www.gnu.org/software/libc/manual/612.1 Utility Argument Syntax, http://pubs.opengroup.org/onlinepubs/9699919799/

    basedefs/V1_chap12.html

    http://www.eglibc.org/homehttp://pubs.opengroup.org/onlinepubs/9699919799/http://www.gnu.org/software/libc/manual/http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html

  • 6. Variables de entorno 5

    Una opcin es un guin - seguido de un carcter alfanumrico, por ejemplo, -o.

    Una opcin requiere un parmetro que debe aparecer inmediatamente despus de laopcin, por ejemplo, para -o lo siguiente: -o parmetro o -oparmetro.

    Las opciones que no requieren parmetros pueden agruparse detrs de un guin, porejemplo, -lst es equivalente a -t -l -s.

    Las opciones puede aparecer en cualquier orden, as -lst es equivalente a -tls.

    Las opciones pueden aparecer muchas veces.

    El parmetro -- indica el fin de las opciones en cualquier caso.

    La opcin - a menudo se indica para representar alguna entrada estndar.

    La funcin getopt()7 del estndar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX.1-2008. getopt() est implementada en libc89. Puedes vercdigo de ejemplo comentado en el fichero ejemplo-getopt.c. El fichero ejemplo-getoptlong.ccontiene un ejemplo de procesado de rdenes al estilo de GNU (por ejemplo, --help y -hcomo rdenes compatibles). Este segundo ejemplo no lo veremos en clase.

    5.2. Ejercicios

    Descarga el cdigo de ejemplo de getopt() de la documentacin de glibc10. Lee elcdigo, complalo, ejectalo para comprobar que admite las opciones de parmetros POSIX.Trata de entender el cdigo y aade ms opciones (por ejemplo una sin parmetros y otra conparmetros). Debes consultar la seccin Using the getopt function de la documentacin11

    para saber cmo funciona getopt, qu valores espera y qu comportamiento tiene.

    6. Variables de entorno

    6.1. Introduccin y documentacin

    Una variable de entorno es un objeto designado para contener informacin usada poruna o ms aplicaciones. La variables de entorno se asociacin a toda la mquina, pero tam-bin a usuarios individuales. Si utilizas bash, puedes consultar las variables de entorno detu sesin con el comando env. Tambin puedes consultar o modificar el valor de una varia-ble de forma individual:

    $ env$ ...$ echo $LANGes_ES.UTF-8$ export LANG=en_GB.UTF-8

    7http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html8http://www.gnu.org/software/libc/manual/html_node/Getopt.html9Notas sobre portabilidad en http://www.gnu.org/software/gnulib/manual/gnulib.html#

    getopt10http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html11http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

    http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.htmlhttp://www.gnu.org/software/libc/manual/html_node/Getopt.htmlhttp://www.gnu.org/software/gnulib/manual/gnulib.html#getopthttp://www.gnu.org/software/gnulib/manual/gnulib.html#getopthttp://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.htmlhttp://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

  • 6 Programacin y Administracin de Sistemas 2011-2012

    6.2. Ejercicios

    Utilizando la funcin getenv()12, haz un programa que dependiendo del idioma de lasesin de usuario, imprima un mensaje con su carpeta personal en castellano o en ingls.Puedes ver cdigo de ejemplo en el fichero ejemplo-getenv.c.

    7. Obtencin de informacin de un usuario/a

    7.1. Introduccin y documentacin

    En los sistemas operativos la base de datos de usuarios puede ser local y/o remota. Porejemplo, en GNU/Linux puedes ver los usuarios y grupos locales en los ficheros /etc/passwdy /etc/group. Si los usuarios no son locales normalmente se encuentran en una mquinaremota a la que se accede por un protocolo especfico. Algunos ejemplos son el servicio deinformacin de red (NIS, Network Information Service) o el protocolo ligero de acceso a di-rectorios (LDAP, Lightweight Directory Access Protocol). En la actualizad NIS apenas se usa yLDAP es el estndar para autenticar usuarios tanto en sistemas Unix o GNU/Linux comoen sistemas Windows.

    En el caso de GNU/Linux, la autenticacin de usuarios la realizan los mdulos de au-tenticacin PAM (Pluggable Authentication Module). PAM es un mecanismo de autenticacinflexible que permite abstraer las aplicaciones del proceso de identificacin. La bsqueda desu informacin asociada la realiza el servicio NSS (Name Service Switch), que provee una in-terfaz para configurar y acceder a diferentes bases de datos de cuentas de usuarios y clavescomo /etc/passwd, /etc/group, /etc/hosts, LDAP, etc.

    POSIX presenta una interfaz para el acceso a la informacin de usuarios que abstrae alprogramador de dnde se encuentran los usuarios (en bases de datos locales y/o remotas,con distintos formatos, etc.). Por ejemplo, la llamada getpwuid() devuelve una estructuracon informacin de un usuario. El sistema POSIX se encarga de intercambiar informacincon NSS para conseguir la informacin del usuario. NSS leer ficheros en el disco duro orealizar consultas a travs de la red para conseguir esa informacin.

    7.2. Ejercicios

    Puedes ver las funciones y estructuras de acceso a la informacin de usuarios/as y gru-pos en los siguientes ficheros de cabecera: /usr/include/pwd.h /usr/include/grp.h.La funcin getpwnam()13 permite obtener informacin de un usuario/a. Mira el programade ejemplo de getpwnam() y amplalo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a travs del identificador del grupo. Puedes ver cdigo de ejemplo enel fichero ejemplo-infousuario.c.

    12http://pubs.opengroup.org/onlinepubs/009604599/functions/getenv.html13http://pubs.opengroup.org/onlinepubs/009604599/functions/getpwnam.html

    http://www.gnu.org/software/libc/manual/html_node/User-Database.html14http://www.gnu.org/software/libc/manual/html_node/Group-Database.html

    http://pubs.opengroup.org/onlinepubs/009604599/functions/getenv.htmlhttp://pubs.opengroup.org/onlinepubs/009604599/functions/getpwnam.htmlhttp://www.gnu.org/software/libc/manual/html_node/User-Database.htmlhttp://www.gnu.org/software/libc/manual/html_node/Group-Database.html

  • 9. Creacin de procesos Fork y Exec 7

    8. Ejercicio resumen 1 (0.5 punto)

    Realizar un programa que obtenga e imprima la informacin de un usuario (todos loscampos de la estructura passwd) pasado por el parmetro -u. Si adems se le pasa la opcin-g deber buscar e imprimir la informacin del grupo del usuario (nmero ID del grupo ynombre).

    Si se le pasa la opcin -e imprimir el mensaje en castellano, y la opcin -s hace que loimprima en ingls. Si no se le pasa ni -e ni -s se mirar la variable de entorno LANG paramostrar la informacin. Por ejemplo, las siguientes llamadas seran vlidas:

    # Obtener la informacin de un usuario usando el idioma# configurado en LANG$ infousuario -u i02samoj# Obtener la informacin de un usuario forzando el# idioma en castellano$ infousuario -u i02samoj -e# Obtener la informacin de un usuario aadiendo la# informacin de su grupo principal e imprimiendo todo en ingls$ infousuario -u i02samoj -s -g

    El control de errores debe ser el siguiente:

    Asegurar que se pasa el nombre del usuario (tienes un ejemplo de cmo controlar quese pasa el parmetro de una opcin en el ejemplo-getopt.c).

    Las opciones -e y -s no pueden activarse a la vez.

    Sugerencia: empezar por el cdigo de ejemplo ejemplo-getopt.c. Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcin esencial (porejemplo el nombre de usuario). Despus debe ir la lgica del programa dependiendo de lasopciones que se hayan reconocido. Se pueden hacer funciones para simplificar la funcinmain. Por ejemplo, una funcin para imprimir la informacin del usuario en castellano/in-gls a la que se le pase la estructura struct passwd y una opcin. Una sugerencia para elesquema general puede ser:

    1. Procesar opciones de entrada.

    2. Usar la variable de entorno LANG si las flags de las opciones -e o -s estn a cero.

    3. Llamar a una funcin que imprima la informacin de un usuario en ingls o castellanocon las opciones (login, grupo si/no, idioma).

    9. Creacin de procesos Fork y Exec

    9.1. Introduccin y documentacin

    En general, en sistemas operativos y lenguajes de programacin, se llama bifurcacin ofork a la creacin de un subproceso copia del proceso que llama a la funcin. El subprocesocreado, o proceso hijo, proviene del proceso originario, o proceso padre. Los procesos

  • 8 Programacin y Administracin de Sistemas 2011-2012

    pid=fork()

    case 0:// hijo

    default:// padre

    Figura 4: Esquema de llamadas y procesos generados por fork() en el ejemplo.

    resultantes son idnticos, salvo que tienen distinto nmero de proceso (PID)15. En UNIXotra forma de crear subprocesos es utilizar tuberas o pipes, las cules son esenciales para lacomunicacin inter-procesos, por ejemplo:

    $ find . -name "*.c" -print | wc -l

    En C se crea un subproceso con llamando a la funcin fork()16. Tienes un pequeomanual y mucho cdigo de ejemplo en [6]. Puedes ver un cdigo con muchos comentariosen la entrada de Wikipedia17. El nuevo proceso hereda varias propiedades del proceso padre(variables de entorno, descriptores de ficheros, etc. ). En esta asignatura no entraremos enqu sucede internamente a nivel del sistema operativo. Despus de una llamada exitosa afork habr dos copias del cdigo original ejecutndose a la vez. En el proceso original, elvalor devuelto de fork ser el identificador del proceso hijo. En cambio, en el proceso hijoel valor devuelto por fork ser 0.

    9.2. Ejercicios y ejemplos

    El listado siguiente (ejemplo-fork.c) es un ejemplo de uso de fork que controla qutipo de proceso es el que ejecuta el cdigo utilizando el valor devuelto por la funcin, as co-mo otras funciones POSIX para obtener informacin de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4):

    #include #include #include

    int main(){

    pid_t rf;rf = fork();switch (rf)

    15http://www.gnu.org/software/libc/manual/html_node/Processes.html16http://pubs.opengroup.org/onlinepubs/9699919799/17http://es.wikipedia.org/wiki/Bifurcaci%C3%B3n_%28sistema_operativo%29

    http://www.gnu.org/software/libc/manual/html_node/Processes.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/http://es.wikipedia.org/wiki/Bifurcaci%C3%B3n_%28sistema_operativo%29

  • 9. Creacin de procesos Fork y Exec 9

    {case -1:

    printf ("No he podido crear el proceso hijo \n");exit(-1);

    case 0:printf ("Soy el hijo, mi PID es %d y mi PPID es %d \n",

    getpid(), getppid());sleep (5);break;

    default:printf ("Soy el padre, mi PID es %d y el PID de mi hijo es

    %d \n", getpid(), rf);sleep (10);

    }

    printf ("Final de ejecucin de %d \n", getpid());exit (0);

    }

    Un ejemplo de llamada a este cdigo sera:

    $ ./ejemplo-forkSoy el padre, mi PID es 23455 y el PID de mi hijo es 23456Soy el hijo, mi PID es 23456 y mi PPID es 23455Final de ejecucin de 23456Final de ejecucin de 23455

    En este ejemplo el proceso padre no queda bloqueado esperando al hijo, prueba a ponerun valor menor de espera (sleep) para el padre que para el hijo:

    $ ./ejemplo-forkSoy el padre, mi PID es 23437 y el PID de mi hijo es 23438Soy el hijo, mi PID es 23438 y mi PPID es 23437Final de ejecucin de 23437$ Final de ejecucin de 23438

    Si quisiramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen, debemos utilizar la funcin wait18. El valor devuelto por la funcin wait es elPID del proceso hijo que se est esperando que termine, si se le ha pasado un PID comoargumento. Si slo se le pasa &status, wait() espera a que terminen todos los procesoshijos y devuelve el PID del ltimo proceso en terminar. Un ejemplo:

    #include #include

    int main(){pid_t pid;int status, died;

    18www.gnu.org/software/libc/manual/html_node/Process-Completion.html

    www.gnu.org/software/libc/manual/html_node/Process-Completion.html

  • 10 Programacin y Administracin de Sistemas 2011-2012

    switch(pid=fork()){case -1: printf("cant fork\n");

    exit(-1);case 0 : sleep(2); // cdigo que ejecuta el hijo

    exit(3);default: died= wait(&status); // cdigo que ejecuta el padre}

    }

    En ocasiones puede interesar ejecutar un programa distinto, no diferentes partes de l, yse quiere iniciar este segundo proceso diferente desde el programa principal. La familia defunciones exec() permiten iniciar un programa dentro de otro programa. En lugar de crearuna copia del proceso, como fork(), exec() provoca el reemplazo total del programaque llama a la funcin por el programa llamado. Por ese motivo se suele utilizar exec()junto con fork(), de forma que sea un proceso hijo el que cree el nuevo proceso para queel proceso padre no sea destruido. Podemos ver este mecanismo en el siguiente cdigo deejemplo:

    #include #include #include #include

    int main(){

    pid_t pid;int status, died;

    char *args[] = {"/bin/ls", "-r", "-t", "-l", (char *) 0 };

    switch(pid=fork()){case -1:

    printf("cant fork\n");exit(-1);

    case 0 :printf("child\n"); // cdigo que ejecuta el hijoexecv("/bin/ls", args);

    default:died= wait(&status); // cdigo que ejecuta el padre

    }

    return(0);}

  • 10. Seales entre procesos 11

    10. Seales entre procesos

    10.1. Introduccin y documentacin

    Las seales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento. Otras formas alternativas o complementarias decomunicacin entre procesos son las tuberas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open, mq_send. . . ). Losprogramas pueden disearse para capturar una o varias seales proporcionando una fun-cin que las maneje. Este tipo de funciones se llaman tcnicamente callbacks o retrollamadas.Una callback es una referencia a un trozo de cdigo ejecutable, normalmente una funcin,que se pasa como parmetro a otro cdigo. Esto permite, por ejemplo, que una capa de bajonivel del software llame a la subrutina o funcin definida en una capa superior (ver Figura5, fuente Wikipedia19).

    Application program

    Software library

    Main program

    Library function

    callsCallback function

    calls

    Figura 5: Esquema del funcionamiento de las callbacks o retrollamadas.

    Por ejemplo, cuando se apaga GNU/Linux, se enva la seal SIGTERM a todos los proce-sos, as los procesos pueden capturar esta seal y terminar de forma adecuada, por ejemploliberando recursos, cerrando ficheros abiertos, etc. La funcin signal20 permite asociar unadeterminada funcin (a travs de un puntero a funcin) a una seal identificada por un en-tero (SIGTERM, SIGKILL, etc.).

    #include

    sighandler_t signal(int signum, sighandler_t handler);...

    10.2. Ejercicios y ejemplos

    El cdigo de ejemplo ejemplo-signals.c21 contiene ejemplos captura de seales PO-SIX enviadas a un programa. Recuerda que la funcin signal() no llama a ninguna funcin,

    19http://en.wikipedia.org/wiki/Callback_%28computer_science%2920http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html21Fuente http://www.amparo.net/ce155/signals-ex.html

    http://en.wikipedia.org/wiki/Callback_%28computer_science%29http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.htmlhttp://www.amparo.net/ce155/signals-ex.html

  • 12 Programacin y Administracin de Sistemas 2011-2012

    lo que hace es asociar una funcin del programador a eventos que se generan en el sistema,esto es, pasar un puntero a una funcin.

    $ ./ejemplo-signalCannot handle SIGKILL!I caught the SIGHUP signal!I caught the SIGTERM signal!Terminado (killed)# En otra terminal: obtener el PID del proceso$ ps -e|grep signal31188 pts/0 00:00:05 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal # mandamos seal SIGTERM$ killall ejemplo-signal -9 # Forzamos parar el programa con

    SIGKILL

    11. sockets POSIX

    11.1. Introduccin y conceptos bsicos

    En esta seccin haremos una pequea introduccin a los sockets POSIX, una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre s a travs de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCP/IP.Como esta no es una asignatura especfica de redes, aprenderemos algunos conceptos y al-goritmos bsicos para la comunicacin pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles. Si tienes duda sobre alguna funcin, hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiang.com [7],nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras. Acontinuacin daremos algunas definiciones.

    Protocolo: En una red de ordenadores hay varios ordenadores que estn conectados entre sipor un medio fsico (cable, ondas inalmbricas, etc.) a travs del cul puede transmitir-se informacin. Para que exista esta comunicacin debe haber un idioma o protocolocomn entre los equipos. Hay muchsimos protocolos de comunicacin, entre los cua-les el ms extendido es el TCP/IP. El ms extendido porque es el que se utiliza enInternet.

    socket: Un socket no es ms que un canal de comunicacin entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador. Desde el puntode vista de programacin, un socket no es ms que un fichero que se abre de unamanera especial. Una vez abierto se pueden escribir y leer datos de l con las habitualesfunciones de read() y write() del lenguaje C. Existen bsicamente dos tipos decanales de comunicacin o sockets, los orientados a conexin (por ejemplo TCP)y los no orientados a conexin (por ejemplo UDP). Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexin.

    arquitectura cliente-servidor: La arquitectura cliente-servidor es un modelo de aplicacindistribuida en el que las tareas se reparten entre los proveedores de recursos o servicios,

  • 11. sockets POSIX 13

    llamados servidores, y los demandantes, llamados clientes. Por ejemplo, la World WideWeb (WWW) se implementa con este modelo. El servidor es el programa que permanecepasivo a la espera de que alguien solicite conexin con l, normalmente, para pedirlealgn dato. Cliente es el programa que solicita la conexin para, normalmente, pedirdatos al servidor.

    11.2. Algoritmo bsico Cliente-Servidor

    La Figura 6 muestra el diagrama de flujo general de la comunicacin Cliente-Servidorutilizando sockets.

    Servidor

    socket()

    connect()

    send()

    recv()

    closeSocket()

    Cliente

    socket()

    bind()

    listen()

    accept()

    recv()

    send()

    recv()

    closeSocket()

    El cliente enva datos yel servidor los recive

    El servidor enva datos y el cliente los recive

    El cliente manda un mensaje para finalizar la conexin

    Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

    Figura 6: Diagrama de flujo de la implementacin del modelo Cliente-Servidor orientado ala conexin con sockets POSIX.

  • 14 Programacin y Administracin de Sistemas 2011-2012

    11.3. Pasos de programacin C en el lado Servidor

    Con C en Unix/Linux, los pasos que debe seguir un programa servidor son los siguientes[7]:

    Apertura de un socket, mediante la funcin socket(). Esta funcin devuelve un des-criptor de fichero normal, como puede devolverlo open() o fopen(). La funcinsocket() no hace absolutamente nada respecto a iniciar la comunicacin, salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociara una conexin en red.

    Avisar al sistema operativo de que hemos abierto un socket y queremos que asocienuestro programa a dicho socket. Se consigue mediante la funcin bind(). El siste-ma todava no atender a las conexiones de clientes, simplemente anota que cuandoempiece a hacerlo, tendr que avisarnos a nosotros. Es en esta llamada cuando se debeindicar el nmero de servicio (o puerto) al que se quiere atender.

    Avisar al sistema de que comience a atender dicha conexin de red. Se consigue me-diante la funcin listen(). A partir de este momento el sistema operativo anotarla conexin de cualquier cliente para pasrnosla cuando se lo pidamos. Si llegan clien-tes ms rpido de lo que somos capaces de atenderlos, el sistema operativo hace unacola con ellos y nos los ir pasando segn vayamos pidindolo.

    Pedir y aceptar las conexiones de clientes al sistema operativo. Para ello hacemos unallamada a la funcin accept(). Esta funcin le indica al sistema operativo que nos dal siguiente cliente de la cola. Si no hay clientes se quedar bloqueada hasta que algncliente se conecte.

    Escribir y recibir datos del cliente, por medio de las funciones write() y read(), queson exactamente las mismas que usamos para escribir o leer de un fichero. Obviamente,tanto cliente como servidor deben saber qu datos esperan recibir, qu datos debenenviar y en qu formato, por ejemplo el protocolo HTTP y el formato HTML o XHTML.

    Cierre de la comunicacin y del socket, por medio de la funcin close(), que es lamisma que sirve para cerrar un fichero.

    11.4. Pasos de programacin C en el lado Cliente

    Nosotros no veremos la parte del cliente, ya que cualquier navegador web ser el clientede nuestro servidor. Los pasos que debe seguir un programa cliente son los siguientes [7]:

    Apertura de un socket, como el servidor, por medio de la funcin socket().

    Solicitar conexin con el servidor por medio de la funcin connect(). Dicha funcinquedar bloqueada hasta que el servidor acepte nuestra conexin o bien si no hayservidor en el sitio indicado, saldr dando un error. En esta llamada se debe facilitar ladireccin IP del servidor y el nmero de servicio que se desea.

    Escribir y recibir datos del servidor por medio de las funciones write() y read().

    Cerrar la comunicacin por medio de close().

  • 12. Todo junto: un servidor web bsico en C 15

    Figura 7: Ejemplo de ejecucin del servidor web con la llamada ejemplo-webserver -p8080 -r htdocs

    12. Todo junto: un servidor web bsico en C

    12.1. Introduccin y cdigo

    En esta seccin vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las prcticas. Esta seccin la trabajaremos directamente sobre el cdigode ejemplo ejemplo-webserver.c. Este ejemplo es un cdigo ampliado descargado deinternet con algunas funciones auxiliares que se han aadido para facilitar los ejercicios.Pregunta todas las dudas que tengas durante la explicacin del cdigo. El objetivo es tratarde reconocer los pasos del modelo Cliente-Servidor de la Figura 6 a grandes rasgos y sinperderse en los detalles, ya que no se pedir ninguna modificacin de las partes de cdigorelativas a la comunicacin.. La Figura 8 muestra el funcionamiento general del cdigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultnea.

  • 16 Programacin y Administracin de Sistemas 2011-2012

    Servidor

    socket()

    connect()

    send()

    recv()

    closeSocket()

    Cliente

    socket()

    bind()

    listen()

    accept()

    recv()

    send()

    recv()

    closeSocket()

    HTTP/1.0 200 OK....Datos

    El cliente manda un mensaje para finalizar la conexin

    Diagrama de flujodel ejemplo de servidor web bsico

    startServer()

    while(1) { ... fork() ...}

    respond()

    fork()

    GET /hola.html HTTP/1.1

    La llamada a accept() crea un nuevosocket para atender la conexinque deber ser cerrado al finalizarel intercambio de datos.

    El socket creado por el procesoprincipal debera ser cerradoal finalizar el programa, por ejemplo capturando lasseales SIGTERM, SIGINT...

    Figura 8: Diagrama de flujo de la implementacin del modelo Cliente-Servidor orientado ala conexin con sockets POSIX.

    12.2. Ejercicios

    Arranca y para el servidor siguiendo la ayuda de la lnea de comandos. Prueba a conec-tarte a l a travs del navegador y prueba a cambiar las opciones. Si no sabes HTML, miralos ficheros de ejemplo del directorio htdocs del paquete de prcticas.

    Para arrancar el servidor, que escuche en el puerto 8080 y que utilice el directorio htdocscomo raz para servir ficheros web:

    $ ./ejemplo-webserver -p 8080 -r htdocs

    ahora visita la direccin http://localhost:8080/ y comprueba que puedes navegar porlas pginas alojadas en el servidor. En el navegador deberas obtener un resultado similar alde la Figura 7. Puedes probar a ejecutar el servidor en ts.uco.es, en este caso la direccin

    http://localhost:8080/

  • 13. Ejercicio resumen 2 (1 punto) 17

    sera http://ts.uco.es:8080/. Si esto lo hacis varias personas, tal vez tengis quecambiar el puerto porque slo una aplicacin puede escuchar en un puerto, este mensajede error os indicara que ya hay una aplicacin asociada al puerto que pretendis usar:

    $ ./ejemplo-webserver -p 8080 -r htdocs$ socket() or bind(): Address already in use

    Este mensaje de error puede obtenerse an cuando haya finalizado la ejecucin de pro-grama que escucha el puerto. Aunque el documento es antiguo y la explicacin tal vez nosea precisa, puedes leer una explicacin de por qu pasa esto en [8]

    13. Ejercicio resumen 2 (1 punto)

    Para este ejercicio partiremos del cdigo ejemplo-webserver.c. El Makefile del pa-quete de prcticas ya incluye una regla para compilar el fichero webserverex.c. Ejercicios:

    1. La funcin webServerLog() implementa un pequeo sistema de registro o log (noptimo, por supuesto). Esta funcin es similar a printf(). Utilizndola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccess.log y los errores en el fichero error.log. Por ejemplo, puedes hacer lassiguientes llamadas:

    webServerLog(WS_LOG_ACCESS, \"Servidor iniciado en el puerto %s", PORT);

    webServerLog(WS_LOG_ERROR, "Error en la conexin");

    No necesitas reemplazar todos los mensajes, pero si los ms significativos: cuando nose puede iniciar el servidor por estar el puerto ocupado, el inicio o parada del servidory las peticiones HTTP que llegan al servidor.

    2. Modifica el cdigo del servidor web para que tenga una nueva opcin -f. Cuando sepase esta opcin, el servidor deber incluir una foto del Fary en todas las pginas webque sirva. Una imagen se incluye en HTML con el cdigo insertado entre las eti-quetas y , que es donde va el contenido en si de una pgina HTML.

    Figura 9: El Fary

    http://ts.uco.es:8080/

  • 18 Programacin y Administracin de Sistemas 2011-2012

    Ten en cuenta que el navegador har una peticin por cada fichero .html, y otra(s) porcada imagen (u otros datos) contenidos en la web. As, si una web tiene una imagen,el navegador pedir primero el fichero .html con un GET /hola.html HTTP/1.1 ycuando lo abra y detecte la etiqueta har otra peticin GET /fichero.jpgHTTP/1.1 para que el servidor le enve el fichero de la imagen22. Aydate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile(). Acurdate deactualizar la ayuda del programa.

    3. Captura algunas llamadas al sistema (SIGTERM, SIGINT y SIGHUP) para gestionar elfin del programa adecuadamente. Puedes asociar estas tres seales con la misma fun-cin de parar el servidor. Se deberan finalizar y cerrar adecuadamente las conexionesy ficheros abiertos. Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y envindole la seal SIGTERM respectivamente. Porejemplo, start-server.sh y stop-server.sh.

    4. Captura la URL solicitada por el cliente. Si se pide la URL http://servidor:puerto/infousuario/i02samoj el servidor debe generar una web con la informacin delusuario. Con el cdigo del ejercicio resumen 1 y usando un fichero temporal no debe-ra ser muy difcil.

    Para el segundo ejercicio, una llamada similar a

    $ ./ejemplo-webserver -p 8080 -r htdocs/ -f

    debera producir un resultado similar en el navegador al de la Figura 10.

    14. Trabajo futuro

    Algunas ideas que no ha dado tiempo a hacer:

    Utilizar el patrn de diseo singleton para guardar la configuracin del programa.

    Controlar la destruccin de subprocesos del servidor pasado un tiempo.

    Comunicacin inter-procesos con diferentes alternativas (tuberas, POSIX MQ, etc.).

    Capturar cmo ha muerto un proceso WEXITSTATUS, WTERMSIG...

    Hacer que el servidor sirva cdigo generado con PHP (por ejemplo recogiendo la salidade php ejemplo.php)

    22La peticin de estos ficheros auxiliares se hace al servidor que sirve la web, pero tambin se puede hacer aotro si el fichero se encuentra en otro sitio web. Esto ocurre por ejemplo cuando se inserta un vdeo de youtube osimilares en una pgina.

    23En el cdigo del servidor web se proporciona la funcin strcasestr(cadena, subcadena) para facili-tar uno de los ejercicios. Esta funcin busca una subcadena dentro de una cadena. Devuelve un 0 si no encuentrala subcadena o la posicin de la subcadena si la encuentra, es decir, un valor mayor que cero.

    http://servidor:puerto/infousuario/i02samojhttp://servidor:puerto/infousuario/i02samoj

  • 14. Trabajo futuro 19

    Figura 10: Ejemplo del resultado de la ejecucin del servidor web para implementar la op-cin -f.

  • 20 Programacin y Administracin de Sistemas 2011-2012

    Referencias

    [1] Wikipedia. Posix wikipedia, la enciclopedia libre, 2012. [Internet; descargado 12-abril-2012]. Available from: http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603.

    [2] The IEEE and The Open Group. Posix.1-2008 the open group base specifications issue 7,2008. Available from: http://pubs.opengroup.org/onlinepubs/9699919799/.

    [3] Proyecto GNU. Gnu c library, 2012. Available from: http://www.gnu.org/software/libc/libc.html.

    [4] Brian W. Kernighan, Dennis Ritchie, and Dennis M. Ritchie. C Programming Language(2nd Edition). Pearson Educacin, 2 edition, 1991.

    [5] Wikipedia. Glibc wikipedia, la enciclopedia libre, 2012. [Internet; descargado 12-abril-2012]. Available from: http://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698.

    [6] Tim Love. Fork and exec, 2008. Available from: http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.html.

    [7] chuidiang.com. Programacin de sockets en c de unix/linux, 2007. Available from:http://www.chuidiang.com/clinux/sockets/sockets_simp.php.

    [8] Andrew Gierth Vic Metcalfe and other contributers. Programming UNIX Sockets inC - Frequently Asked Questions. 4.2 Why dont my sockets close?, 1996. Availa-ble from: http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2.

    [9] Wikipedia. Dennis ritchie wikipedia, la enciclopedia libre, 2012. Available from: http://es.wikipedia.org/wiki/Dennis_Ritchie.

    http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603http://pubs.opengroup.org/onlinepubs/9699919799/http://www.gnu.org/software/libc/libc.htmlhttp://www.gnu.org/software/libc/libc.htmlhttp://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698http://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.htmlhttp://www-h.eng.cam.ac.uk/help/tpl/unix/fork.htmlhttp://www.chuidiang.com/clinux/sockets/sockets_simp.phphttp://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2http://es.wikipedia.org/wiki/Dennis_Ritchiehttp://es.wikipedia.org/wiki/Dennis_Ritchie

    1 Introduccin a POSIX2 Objetivos3 Entrega de prcticas4 Documentacin de POSIX y las bibliotecas5 Procesado de lnea de comandos tipo POSIX5.1 Introduccin y documentacin5.2 Ejercicios

    6 Variables de entorno6.1 Introduccin y documentacin6.2 Ejercicios

    7 Obtencin de informacin de un usuario/a7.1 Introduccin y documentacin7.2 Ejercicios

    8 Ejercicio resumen 1 (0.5 punto)9 Creacin de procesos Fork y Exec9.1 Introduccin y documentacin9.2 Ejercicios y ejemplos

    10 Seales entre procesos10.1 Introduccin y documentacin10.2 Ejercicios y ejemplos

    11 sockets POSIX11.1 Introduccin y conceptos bsicos11.2 Algoritmo bsico Cliente-Servidor11.3 Pasos de programacin C en el lado Servidor11.4 Pasos de programacin C en el lado Cliente

    12 Todo junto: un servidor web bsico en C12.1 Introduccin y cdigo12.2 Ejercicios

    13 Ejercicio resumen 2 (1 punto)14 Trabajo futuroReferencias