Práctica3: Programación POSIX - uco.esi02samoj/docencia/pas/practica-POSIX.pdf · Entre otras cosas, el estándar ... compilar y ejecutarse sinproblemasen cualquier sistema operativo

Post on 10-Apr-2018

219 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

Transcript

Praacutectica3 Programacioacuten POSIXProgramacioacuten y Administracioacuten de Sistemas

2011-2012

Javier Saacutenchez Monederojsanchezmucoes

2o curso de Grado en Ingenieriacutea InformaacuteticaDepartamento de Informaacutetica y Anaacutelisis Numeacuterico

Escuela Politeacutecnica SuperiorUniversidad de Coacuterdoba

26 de octubre de 2012

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

paraacutemetros y valores devueltos) que deben proporcionar todos los sistemas operativosque quieran satisfacer el estaacutendar De esta forma si una aplicacioacuten hace un buen uso deestas funciones deberaacute compilar y ejecutarse sin problemas en cualquier sistema operativoPOSIX En esta praacutectica vamos a conocer queacute es el estaacutendar POSIX y una implementa-cioacuten de la biblioteca C de POSIX la biblioteca libre GNU C Library o glibc En Moodle seadjunta el fichero pas-practica3tgz que contiene coacutedigo de ejemplo de las funcio-nes que iremos viendo en clase

Iacutendice

1 Introduccioacuten a POSIX 2

2 Objetivos 4

3 Entrega de praacutecticas 4

4 Documentacioacuten de POSIX y las bibliotecas 4

5 Procesado de liacutenea de comandos tipo POSIX 451 Introduccioacuten y documentacioacuten 452 Ejercicios 5

6 Variables de entorno 561 Introduccioacuten y documentacioacuten 562 Ejercicios 6

1

2 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

7 Obtencioacuten de informacioacuten de un usuarioa 671 Introduccioacuten y documentacioacuten 672 Ejercicios 6

8 Ejercicio resumen 1 (05 punto) 7

9 Creacioacuten de procesos Fork y Exec 791 Introduccioacuten y documentacioacuten 792 Ejercicios y ejemplos 8

10 Sentildeales entre procesos 11101 Introduccioacuten y documentacioacuten 11102 Ejercicios y ejemplos 11

11 sockets POSIX 12111 Introduccioacuten y conceptos baacutesicos 12112 Algoritmo baacutesico Cliente-Servidor 13113 Pasos de programacioacuten C en el lado Servidor 14114 Pasos de programacioacuten C en el lado Cliente 14

12 Todo junto un servidor web baacutesico en C 15121 Introduccioacuten y coacutedigo 15122 Ejercicios 16

13 Ejercicio resumen 2 (1 punto) 17

14 Trabajo futuro 18

Referencias 18

1 Introduccioacuten a POSIX

Figura 1 Mascota delproyecto GNU (httpwwwgnuorg)

POSIX es el acroacutenimo de Portable Operating System Interface la Xviene de UNIX como sentildea de identidad de la API (Application Pro-gramming Interface interfaz de programacioacuten de aplicaciones) Son unafamilia de estaacutendares de llamadas al sistema operativo definidospor el IEEE (Institute of Electrical and Electronics Engineers Institutode Ingenieros Eleacutectricos y Electroacutenicos) y especificados formalmenteen el IEEE 1003 Persiguen generalizar las interfaces de los sistemasoperativos para que una misma aplicacioacuten pueda ejecutarse en dis-tintas plataformas Estos estaacutendares surgieron de un proyecto denormalizacioacuten de las API y describen un conjunto de interfaces deaplicacioacuten adaptables a una gran variedad de implementaciones desistemas operativos [1] La uacuteltima versioacuten de la especificacioacuten POSIX es del antildeo 2008 se cono-ce por ldquoPOSIX1-2008rdquo ldquoIEEE Std 10031-2008rdquo y por ldquoThe Open Group Technical StandardBase Specifications Issue 7rdquo[2]

1 Introduccioacuten a POSIX 3

Figura 2 Dennis MacAlistair Ritchie Colaboroacute en el disentildeo y desarrollo de los sistemasoperativos Multics y Unix asiacute como el desarrollo de varios lenguajes de programacioacuten comoel C tema sobre el cual escribioacute un ceacutelebre claacutesico de las ciencias de la computacioacuten junto aBrian Wilson Kernighan El lenguaje de programacioacuten C [4]

GNU C Library comuacutenmente conocida como glibc es la biblioteca estaacutendar de lenguajeC de GNU Se distribuye bajo los teacuterminos de la licencia GNU LGPL Esta biblioteca siguetodos los estaacutendares maacutes relevantes como ISO C99 y POSIX1-2008 [3] gnulib tambieacutenconocida como ldquoBiblioteca de portabilidad de GNUrdquo es una coleccioacuten de subrutinas disentildea-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 = GNULinux

En los sistemas en los que se usan estasbibliotecas de C proporcionan y definen lasllamadas al sistema y otras funciones baacutesi-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 eacutel comoldquoGNULinuxrdquo para reconocer que el siste-

ma lo compone tanto el nuacutecleo 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 aacuterboles listas enlazadas tablas hash etc y un entorno deorientacioacuten a objetos en C

En estas praacutecticas utilizaremos la biblioteca glibc como implementacioacuten de programa-

1httpeswikipediaorgwikiControversia_por_la_denominaciC3B3n_GNULinux2httplibrarygnomeorgdevelglib

4 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

cioacuten del API POSIX Algunas distribuciones de GNULinux como Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3 pero a efectos de programacioacuten no deberiacutea ha-ber diferencias

2 Objetivos

Conocer algunas rutinas POSIX y su implementacioacuten glibc

Aprender a utilizar bibliotecas externas en nuestros programas

Aprender coacutemo funcionan internamente algunas partes de GNULinux

Mejorar la programacioacuten 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 praacutecticas

Se pediraacute la entrega y defensa de algunos ejercicios resuacutemenes que integren varios de losconceptos y funciones estudiadas en clase Las praacutecticas deben realizarse a nivel individualy se utilizaraacuten mecanismos para comprobar que se han realizado y entendido

4 Documentacioacuten de POSIX y las bibliotecas

Documentacioacuten POSIX1-2008 Especificacioacuten del estaacutendar POSIX Dependiendo de la par-te que documente es maacutes o menos pedagoacutegica4

Documentacioacuten GNU C Library Esta documentacioacuten incluye muchos de los conceptos queya habeacuteis trabajado en asignaturas de introduccioacuten a la programacioacuten o de sistemasoperativos Es una guiacutea completa de programacioacuten en el lenguaje C pero sobre to-do incluye muchas funciones que son esenciales para programar uacutetiles para ahorrartiempo trabajando o para garantizar la portabilidad del coacutedigo entre sistemas POSIX5

5 Procesado de liacutenea de comandos tipo POSIX

51 Introduccioacuten y documentacioacuten

Los paraacutemetros que procesa un programa en sistemas POSIX deben seguir un estaacutendarde formato y respuesta esperada6 Un resumen de lo definido en el estaacutendar es lo siguiente

3httpwwweglibcorghome4httppubsopengrouporgonlinepubs96999197995httpwwwgnuorgsoftwarelibcmanual6121 Utility Argument Syntax httppubsopengrouporgonlinepubs9699919799

basedefsV1_chap12html

6 Variables de entorno 5

Una opcioacuten es un guioacuten rsquo-rsquo seguido de un caraacutecter alfanumeacuterico por ejemplo -o

Una opcioacuten requiere un paraacutemetro que debe aparecer inmediatamente despueacutes de laopcioacuten por ejemplo para -o lo siguiente -o paraacutemetro o -oparaacutemetro

Las opciones que no requieren paraacutemetros pueden agruparse detraacutes de un guioacuten porejemplo -lst es equivalente a -t -l -s

Las opciones puede aparecer en cualquier orden asiacute -lst es equivalente a -tls

Las opciones pueden aparecer muchas veces

El paraacutemetro -- indica el fin de las opciones en cualquier caso

La opcioacuten - a menudo se indica para representar alguna entrada estaacutendar

La funcioacuten getopt()7 del estaacutendar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX1-2008 getopt() estaacute implementada en libc89 Puedes vercoacutedigo de ejemplo comentado en el fichero ejemplo-getoptc El fichero ejemplo-getoptlongccontiene un ejemplo de procesado de oacuterdenes al estilo de GNU (por ejemplo --help y -hcomo oacuterdenes compatibles) Este segundo ejemplo no lo veremos en clase

52 Ejercicios

Descarga el coacutedigo de ejemplo de getopt() de la documentacioacuten de glibc10 Lee elcoacutedigo compiacutelalo ejecuacutetalo para comprobar que admite las opciones de paraacutemetros POSIXTrata de entender el coacutedigo y antildeade maacutes opciones (por ejemplo una sin paraacutemetros y otra conparaacutemetros) Debes consultar la seccioacuten Using the getopt function de la documentacioacuten11

para saber coacutemo funciona getopt queacute valores espera y queacute comportamiento tiene

6 Variables de entorno

61 Introduccioacuten y documentacioacuten

Una variable de entorno es un objeto designado para contener informacioacuten usada poruna o maacutes aplicaciones La variables de entorno se asociacioacuten a toda la maacutequina pero tam-bieacuten a usuarios individuales Si utilizas bash puedes consultar las variables de entorno detu sesioacuten con el comando env Tambieacuten puedes consultar o modificar el valor de una varia-ble de forma individual

$ env$ $ echo $LANGes_ESUTF-8$ export LANG=en_GBUTF-8

7httppubsopengrouporgonlinepubs9699919799functionsgetopthtml8httpwwwgnuorgsoftwarelibcmanualhtml_nodeGetopthtml9Notas sobre portabilidad en httpwwwgnuorgsoftwaregnulibmanualgnulibhtml

getopt10httpwwwgnuorgsoftwarelibcmanualhtml_nodeExample-of-Getopthtml11httpwwwgnuorgsoftwarelibcmanualhtml_nodeUsing-Getopthtml

6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

62 Ejercicios

Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

7 Obtencioacuten de informacioacuten de un usuarioa

71 Introduccioacuten y documentacioacuten

En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

72 Ejercicios

Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

9 Creacioacuten de procesos Fork y Exec 7

8 Ejercicio resumen 1 (05 punto)

Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

1 Procesar opciones de entrada

2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

9 Creacioacuten de procesos Fork y Exec

91 Introduccioacuten y documentacioacuten

En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

pid=fork()

case 0 hijo

default padre

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

resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

$ find -name c -print | wc -l

En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

92 Ejercicios y ejemplos

El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

int main()

pid_t rfrf = fork()switch (rf)

15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

9 Creacioacuten de procesos Fork y Exec 9

case -1

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

case 0printf (Soy el hijo mi PID es d y mi PPID es d n

getpid() getppid())sleep (5)break

defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

d n getpid() rf)sleep (10)

printf (Final de ejecucioacuten de d n getpid())exit (0)

Un ejemplo de llamada a este coacutedigo seriacutea

$ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

include ltunistdhgtinclude ltsyswaithgt

int main()pid_t pidint status died

18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

switch(pid=fork())case -1 printf(canrsquot forkn)

exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

int main()

pid_t pidint status died

char args[] = binls -r -t -l (char ) 0

switch(pid=fork())case -1

printf(canrsquot forkn)exit(-1)

case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

return(0)

10 Sentildeales entre procesos 11

10 Sentildeales entre procesos

101 Introduccioacuten y documentacioacuten

Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

include ltsignalhgt

sighandler_t signal(int signum sighandler_t handler)

102 Ejercicios y ejemplos

El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

$ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

SIGKILL

11 sockets POSIX

111 Introduccioacuten y conceptos baacutesicos

En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

112 Algoritmo baacutesico Cliente-Servidor

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

Servidor

socket()

connect()

send()

recv()

closeSocket()

Cliente

socket()

bind()

listen()

accept()

recv()

send()

recv()

closeSocket()

El cliente enviacutea datos yel servidor los recive

El servidor enviacutea datos y el cliente los recive

El cliente manda un mensaje para finalizar la conexioacuten

Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

113 Pasos de programacioacuten C en el lado Servidor

Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

114 Pasos de programacioacuten C en el lado Cliente

Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

Cerrar la comunicacioacuten por medio de close()

12 Todo junto un servidor web baacutesico en C 15

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

12 Todo junto un servidor web baacutesico en C

121 Introduccioacuten y coacutedigo

En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

Servidor

socket()

connect()

send()

recv()

closeSocket()

Cliente

socket()

bind()

listen()

accept()

recv()

send()

recv()

closeSocket()

HTTP10 200 OKDatos

El cliente manda un mensaje para finalizar la conexioacuten

Diagrama de flujodel ejemplo de servidor web baacutesico

startServer()

while(1) fork()

respond()

fork()

GET holahtml HTTP11

La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

122 Ejercicios

Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

$ ejemplo-webserver -p 8080 -r htdocs

ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

13 Ejercicio resumen 2 (1 punto) 17

seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

13 Ejercicio resumen 2 (1 punto)

Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

webServerLog(WS_LOG_ERROR Error en la conexioacuten)

No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

Figura 9 El Fary

18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

Para el segundo ejercicio una llamada similar a

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

deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

14 Trabajo futuro 19

Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

Referencias

[1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

[2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

[3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

[5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

[6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

[7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

[8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

[9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

  • 1 Introduccioacuten a POSIX
  • 2 Objetivos
  • 3 Entrega de praacutecticas
  • 4 Documentacioacuten de POSIX y las bibliotecas
  • 5 Procesado de liacutenea de comandos tipo POSIX
    • 51 Introduccioacuten y documentacioacuten
    • 52 Ejercicios
      • 6 Variables de entorno
        • 61 Introduccioacuten y documentacioacuten
        • 62 Ejercicios
          • 7 Obtencioacuten de informacioacuten de un usuarioa
            • 71 Introduccioacuten y documentacioacuten
            • 72 Ejercicios
              • 8 Ejercicio resumen 1 (05 punto)
              • 9 Creacioacuten de procesos Fork y Exec
                • 91 Introduccioacuten y documentacioacuten
                • 92 Ejercicios y ejemplos
                  • 10 Sentildeales entre procesos
                    • 101 Introduccioacuten y documentacioacuten
                    • 102 Ejercicios y ejemplos
                      • 11 sockets POSIX
                        • 111 Introduccioacuten y conceptos baacutesicos
                        • 112 Algoritmo baacutesico Cliente-Servidor
                        • 113 Pasos de programacioacuten C en el lado Servidor
                        • 114 Pasos de programacioacuten C en el lado Cliente
                          • 12 Todo junto un servidor web baacutesico en C
                            • 121 Introduccioacuten y coacutedigo
                            • 122 Ejercicios
                              • 13 Ejercicio resumen 2 (1 punto)
                              • 14 Trabajo futuro
                              • Referencias

    2 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    7 Obtencioacuten de informacioacuten de un usuarioa 671 Introduccioacuten y documentacioacuten 672 Ejercicios 6

    8 Ejercicio resumen 1 (05 punto) 7

    9 Creacioacuten de procesos Fork y Exec 791 Introduccioacuten y documentacioacuten 792 Ejercicios y ejemplos 8

    10 Sentildeales entre procesos 11101 Introduccioacuten y documentacioacuten 11102 Ejercicios y ejemplos 11

    11 sockets POSIX 12111 Introduccioacuten y conceptos baacutesicos 12112 Algoritmo baacutesico Cliente-Servidor 13113 Pasos de programacioacuten C en el lado Servidor 14114 Pasos de programacioacuten C en el lado Cliente 14

    12 Todo junto un servidor web baacutesico en C 15121 Introduccioacuten y coacutedigo 15122 Ejercicios 16

    13 Ejercicio resumen 2 (1 punto) 17

    14 Trabajo futuro 18

    Referencias 18

    1 Introduccioacuten a POSIX

    Figura 1 Mascota delproyecto GNU (httpwwwgnuorg)

    POSIX es el acroacutenimo de Portable Operating System Interface la Xviene de UNIX como sentildea de identidad de la API (Application Pro-gramming Interface interfaz de programacioacuten de aplicaciones) Son unafamilia de estaacutendares de llamadas al sistema operativo definidospor el IEEE (Institute of Electrical and Electronics Engineers Institutode Ingenieros Eleacutectricos y Electroacutenicos) y especificados formalmenteen el IEEE 1003 Persiguen generalizar las interfaces de los sistemasoperativos para que una misma aplicacioacuten pueda ejecutarse en dis-tintas plataformas Estos estaacutendares surgieron de un proyecto denormalizacioacuten de las API y describen un conjunto de interfaces deaplicacioacuten adaptables a una gran variedad de implementaciones desistemas operativos [1] La uacuteltima versioacuten de la especificacioacuten POSIX es del antildeo 2008 se cono-ce por ldquoPOSIX1-2008rdquo ldquoIEEE Std 10031-2008rdquo y por ldquoThe Open Group Technical StandardBase Specifications Issue 7rdquo[2]

    1 Introduccioacuten a POSIX 3

    Figura 2 Dennis MacAlistair Ritchie Colaboroacute en el disentildeo y desarrollo de los sistemasoperativos Multics y Unix asiacute como el desarrollo de varios lenguajes de programacioacuten comoel C tema sobre el cual escribioacute un ceacutelebre claacutesico de las ciencias de la computacioacuten junto aBrian Wilson Kernighan El lenguaje de programacioacuten C [4]

    GNU C Library comuacutenmente conocida como glibc es la biblioteca estaacutendar de lenguajeC de GNU Se distribuye bajo los teacuterminos de la licencia GNU LGPL Esta biblioteca siguetodos los estaacutendares maacutes relevantes como ISO C99 y POSIX1-2008 [3] gnulib tambieacutenconocida como ldquoBiblioteca de portabilidad de GNUrdquo es una coleccioacuten de subrutinas disentildea-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 = GNULinux

    En los sistemas en los que se usan estasbibliotecas de C proporcionan y definen lasllamadas al sistema y otras funciones baacutesi-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 eacutel comoldquoGNULinuxrdquo para reconocer que el siste-

    ma lo compone tanto el nuacutecleo 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 aacuterboles listas enlazadas tablas hash etc y un entorno deorientacioacuten a objetos en C

    En estas praacutecticas utilizaremos la biblioteca glibc como implementacioacuten de programa-

    1httpeswikipediaorgwikiControversia_por_la_denominaciC3B3n_GNULinux2httplibrarygnomeorgdevelglib

    4 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    cioacuten del API POSIX Algunas distribuciones de GNULinux como Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3 pero a efectos de programacioacuten no deberiacutea ha-ber diferencias

    2 Objetivos

    Conocer algunas rutinas POSIX y su implementacioacuten glibc

    Aprender a utilizar bibliotecas externas en nuestros programas

    Aprender coacutemo funcionan internamente algunas partes de GNULinux

    Mejorar la programacioacuten 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 praacutecticas

    Se pediraacute la entrega y defensa de algunos ejercicios resuacutemenes que integren varios de losconceptos y funciones estudiadas en clase Las praacutecticas deben realizarse a nivel individualy se utilizaraacuten mecanismos para comprobar que se han realizado y entendido

    4 Documentacioacuten de POSIX y las bibliotecas

    Documentacioacuten POSIX1-2008 Especificacioacuten del estaacutendar POSIX Dependiendo de la par-te que documente es maacutes o menos pedagoacutegica4

    Documentacioacuten GNU C Library Esta documentacioacuten incluye muchos de los conceptos queya habeacuteis trabajado en asignaturas de introduccioacuten a la programacioacuten o de sistemasoperativos Es una guiacutea completa de programacioacuten en el lenguaje C pero sobre to-do incluye muchas funciones que son esenciales para programar uacutetiles para ahorrartiempo trabajando o para garantizar la portabilidad del coacutedigo entre sistemas POSIX5

    5 Procesado de liacutenea de comandos tipo POSIX

    51 Introduccioacuten y documentacioacuten

    Los paraacutemetros que procesa un programa en sistemas POSIX deben seguir un estaacutendarde formato y respuesta esperada6 Un resumen de lo definido en el estaacutendar es lo siguiente

    3httpwwweglibcorghome4httppubsopengrouporgonlinepubs96999197995httpwwwgnuorgsoftwarelibcmanual6121 Utility Argument Syntax httppubsopengrouporgonlinepubs9699919799

    basedefsV1_chap12html

    6 Variables de entorno 5

    Una opcioacuten es un guioacuten rsquo-rsquo seguido de un caraacutecter alfanumeacuterico por ejemplo -o

    Una opcioacuten requiere un paraacutemetro que debe aparecer inmediatamente despueacutes de laopcioacuten por ejemplo para -o lo siguiente -o paraacutemetro o -oparaacutemetro

    Las opciones que no requieren paraacutemetros pueden agruparse detraacutes de un guioacuten porejemplo -lst es equivalente a -t -l -s

    Las opciones puede aparecer en cualquier orden asiacute -lst es equivalente a -tls

    Las opciones pueden aparecer muchas veces

    El paraacutemetro -- indica el fin de las opciones en cualquier caso

    La opcioacuten - a menudo se indica para representar alguna entrada estaacutendar

    La funcioacuten getopt()7 del estaacutendar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX1-2008 getopt() estaacute implementada en libc89 Puedes vercoacutedigo de ejemplo comentado en el fichero ejemplo-getoptc El fichero ejemplo-getoptlongccontiene un ejemplo de procesado de oacuterdenes al estilo de GNU (por ejemplo --help y -hcomo oacuterdenes compatibles) Este segundo ejemplo no lo veremos en clase

    52 Ejercicios

    Descarga el coacutedigo de ejemplo de getopt() de la documentacioacuten de glibc10 Lee elcoacutedigo compiacutelalo ejecuacutetalo para comprobar que admite las opciones de paraacutemetros POSIXTrata de entender el coacutedigo y antildeade maacutes opciones (por ejemplo una sin paraacutemetros y otra conparaacutemetros) Debes consultar la seccioacuten Using the getopt function de la documentacioacuten11

    para saber coacutemo funciona getopt queacute valores espera y queacute comportamiento tiene

    6 Variables de entorno

    61 Introduccioacuten y documentacioacuten

    Una variable de entorno es un objeto designado para contener informacioacuten usada poruna o maacutes aplicaciones La variables de entorno se asociacioacuten a toda la maacutequina pero tam-bieacuten a usuarios individuales Si utilizas bash puedes consultar las variables de entorno detu sesioacuten con el comando env Tambieacuten puedes consultar o modificar el valor de una varia-ble de forma individual

    $ env$ $ echo $LANGes_ESUTF-8$ export LANG=en_GBUTF-8

    7httppubsopengrouporgonlinepubs9699919799functionsgetopthtml8httpwwwgnuorgsoftwarelibcmanualhtml_nodeGetopthtml9Notas sobre portabilidad en httpwwwgnuorgsoftwaregnulibmanualgnulibhtml

    getopt10httpwwwgnuorgsoftwarelibcmanualhtml_nodeExample-of-Getopthtml11httpwwwgnuorgsoftwarelibcmanualhtml_nodeUsing-Getopthtml

    6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    62 Ejercicios

    Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

    7 Obtencioacuten de informacioacuten de un usuarioa

    71 Introduccioacuten y documentacioacuten

    En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

    En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

    POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

    72 Ejercicios

    Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

    12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

    httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

    9 Creacioacuten de procesos Fork y Exec 7

    8 Ejercicio resumen 1 (05 punto)

    Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

    Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

    Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

    Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

    1 Procesar opciones de entrada

    2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

    3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

    9 Creacioacuten de procesos Fork y Exec

    91 Introduccioacuten y documentacioacuten

    En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

    8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    pid=fork()

    case 0 hijo

    default padre

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

    resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

    $ find -name c -print | wc -l

    En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

    92 Ejercicios y ejemplos

    El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

    include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

    int main()

    pid_t rfrf = fork()switch (rf)

    15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

    9 Creacioacuten de procesos Fork y Exec 9

    case -1

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

    case 0printf (Soy el hijo mi PID es d y mi PPID es d n

    getpid() getppid())sleep (5)break

    defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

    d n getpid() rf)sleep (10)

    printf (Final de ejecucioacuten de d n getpid())exit (0)

    Un ejemplo de llamada a este coacutedigo seriacutea

    $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

    Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

    include ltunistdhgtinclude ltsyswaithgt

    int main()pid_t pidint status died

    18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

    10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    switch(pid=fork())case -1 printf(canrsquot forkn)

    exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

    exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

    En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

    include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

    int main()

    pid_t pidint status died

    char args[] = binls -r -t -l (char ) 0

    switch(pid=fork())case -1

    printf(canrsquot forkn)exit(-1)

    case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

    defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

    return(0)

    10 Sentildeales entre procesos 11

    10 Sentildeales entre procesos

    101 Introduccioacuten y documentacioacuten

    Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

    include ltsignalhgt

    sighandler_t signal(int signum sighandler_t handler)

    102 Ejercicios y ejemplos

    El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

    19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

    12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

    $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

    SIGKILL

    11 sockets POSIX

    111 Introduccioacuten y conceptos baacutesicos

    En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

    Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

    socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

    arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

    112 Algoritmo baacutesico Cliente-Servidor

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

    Servidor

    socket()

    connect()

    send()

    recv()

    closeSocket()

    Cliente

    socket()

    bind()

    listen()

    accept()

    recv()

    send()

    recv()

    closeSocket()

    El cliente enviacutea datos yel servidor los recive

    El servidor enviacutea datos y el cliente los recive

    El cliente manda un mensaje para finalizar la conexioacuten

    Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

    Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

    14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    113 Pasos de programacioacuten C en el lado Servidor

    Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

    Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

    Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

    Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

    Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

    114 Pasos de programacioacuten C en el lado Cliente

    Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

    Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

    Cerrar la comunicacioacuten por medio de close()

    12 Todo junto un servidor web baacutesico en C 15

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

    12 Todo junto un servidor web baacutesico en C

    121 Introduccioacuten y coacutedigo

    En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

    16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    Servidor

    socket()

    connect()

    send()

    recv()

    closeSocket()

    Cliente

    socket()

    bind()

    listen()

    accept()

    recv()

    send()

    recv()

    closeSocket()

    HTTP10 200 OKDatos

    El cliente manda un mensaje para finalizar la conexioacuten

    Diagrama de flujodel ejemplo de servidor web baacutesico

    startServer()

    while(1) fork()

    respond()

    fork()

    GET holahtml HTTP11

    La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

    El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

    Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

    122 Ejercicios

    Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

    $ ejemplo-webserver -p 8080 -r htdocs

    ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

    13 Ejercicio resumen 2 (1 punto) 17

    seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

    Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

    13 Ejercicio resumen 2 (1 punto)

    Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

    1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

    webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

    webServerLog(WS_LOG_ERROR Error en la conexioacuten)

    No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

    Figura 9 El Fary

    18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

    4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

    Para el segundo ejercicio una llamada similar a

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

    deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

    Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

    Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

    Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

    22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

    14 Trabajo futuro 19

    Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

    20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

    Referencias

    [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

    [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

    [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

    [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

    [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

    [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

    [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

    [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

    • 1 Introduccioacuten a POSIX
    • 2 Objetivos
    • 3 Entrega de praacutecticas
    • 4 Documentacioacuten de POSIX y las bibliotecas
    • 5 Procesado de liacutenea de comandos tipo POSIX
      • 51 Introduccioacuten y documentacioacuten
      • 52 Ejercicios
        • 6 Variables de entorno
          • 61 Introduccioacuten y documentacioacuten
          • 62 Ejercicios
            • 7 Obtencioacuten de informacioacuten de un usuarioa
              • 71 Introduccioacuten y documentacioacuten
              • 72 Ejercicios
                • 8 Ejercicio resumen 1 (05 punto)
                • 9 Creacioacuten de procesos Fork y Exec
                  • 91 Introduccioacuten y documentacioacuten
                  • 92 Ejercicios y ejemplos
                    • 10 Sentildeales entre procesos
                      • 101 Introduccioacuten y documentacioacuten
                      • 102 Ejercicios y ejemplos
                        • 11 sockets POSIX
                          • 111 Introduccioacuten y conceptos baacutesicos
                          • 112 Algoritmo baacutesico Cliente-Servidor
                          • 113 Pasos de programacioacuten C en el lado Servidor
                          • 114 Pasos de programacioacuten C en el lado Cliente
                            • 12 Todo junto un servidor web baacutesico en C
                              • 121 Introduccioacuten y coacutedigo
                              • 122 Ejercicios
                                • 13 Ejercicio resumen 2 (1 punto)
                                • 14 Trabajo futuro
                                • Referencias

      1 Introduccioacuten a POSIX 3

      Figura 2 Dennis MacAlistair Ritchie Colaboroacute en el disentildeo y desarrollo de los sistemasoperativos Multics y Unix asiacute como el desarrollo de varios lenguajes de programacioacuten comoel C tema sobre el cual escribioacute un ceacutelebre claacutesico de las ciencias de la computacioacuten junto aBrian Wilson Kernighan El lenguaje de programacioacuten C [4]

      GNU C Library comuacutenmente conocida como glibc es la biblioteca estaacutendar de lenguajeC de GNU Se distribuye bajo los teacuterminos de la licencia GNU LGPL Esta biblioteca siguetodos los estaacutendares maacutes relevantes como ISO C99 y POSIX1-2008 [3] gnulib tambieacutenconocida como ldquoBiblioteca de portabilidad de GNUrdquo es una coleccioacuten de subrutinas disentildea-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 = GNULinux

      En los sistemas en los que se usan estasbibliotecas de C proporcionan y definen lasllamadas al sistema y otras funciones baacutesi-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 eacutel comoldquoGNULinuxrdquo para reconocer que el siste-

      ma lo compone tanto el nuacutecleo 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 aacuterboles listas enlazadas tablas hash etc y un entorno deorientacioacuten a objetos en C

      En estas praacutecticas utilizaremos la biblioteca glibc como implementacioacuten de programa-

      1httpeswikipediaorgwikiControversia_por_la_denominaciC3B3n_GNULinux2httplibrarygnomeorgdevelglib

      4 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      cioacuten del API POSIX Algunas distribuciones de GNULinux como Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3 pero a efectos de programacioacuten no deberiacutea ha-ber diferencias

      2 Objetivos

      Conocer algunas rutinas POSIX y su implementacioacuten glibc

      Aprender a utilizar bibliotecas externas en nuestros programas

      Aprender coacutemo funcionan internamente algunas partes de GNULinux

      Mejorar la programacioacuten 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 praacutecticas

      Se pediraacute la entrega y defensa de algunos ejercicios resuacutemenes que integren varios de losconceptos y funciones estudiadas en clase Las praacutecticas deben realizarse a nivel individualy se utilizaraacuten mecanismos para comprobar que se han realizado y entendido

      4 Documentacioacuten de POSIX y las bibliotecas

      Documentacioacuten POSIX1-2008 Especificacioacuten del estaacutendar POSIX Dependiendo de la par-te que documente es maacutes o menos pedagoacutegica4

      Documentacioacuten GNU C Library Esta documentacioacuten incluye muchos de los conceptos queya habeacuteis trabajado en asignaturas de introduccioacuten a la programacioacuten o de sistemasoperativos Es una guiacutea completa de programacioacuten en el lenguaje C pero sobre to-do incluye muchas funciones que son esenciales para programar uacutetiles para ahorrartiempo trabajando o para garantizar la portabilidad del coacutedigo entre sistemas POSIX5

      5 Procesado de liacutenea de comandos tipo POSIX

      51 Introduccioacuten y documentacioacuten

      Los paraacutemetros que procesa un programa en sistemas POSIX deben seguir un estaacutendarde formato y respuesta esperada6 Un resumen de lo definido en el estaacutendar es lo siguiente

      3httpwwweglibcorghome4httppubsopengrouporgonlinepubs96999197995httpwwwgnuorgsoftwarelibcmanual6121 Utility Argument Syntax httppubsopengrouporgonlinepubs9699919799

      basedefsV1_chap12html

      6 Variables de entorno 5

      Una opcioacuten es un guioacuten rsquo-rsquo seguido de un caraacutecter alfanumeacuterico por ejemplo -o

      Una opcioacuten requiere un paraacutemetro que debe aparecer inmediatamente despueacutes de laopcioacuten por ejemplo para -o lo siguiente -o paraacutemetro o -oparaacutemetro

      Las opciones que no requieren paraacutemetros pueden agruparse detraacutes de un guioacuten porejemplo -lst es equivalente a -t -l -s

      Las opciones puede aparecer en cualquier orden asiacute -lst es equivalente a -tls

      Las opciones pueden aparecer muchas veces

      El paraacutemetro -- indica el fin de las opciones en cualquier caso

      La opcioacuten - a menudo se indica para representar alguna entrada estaacutendar

      La funcioacuten getopt()7 del estaacutendar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX1-2008 getopt() estaacute implementada en libc89 Puedes vercoacutedigo de ejemplo comentado en el fichero ejemplo-getoptc El fichero ejemplo-getoptlongccontiene un ejemplo de procesado de oacuterdenes al estilo de GNU (por ejemplo --help y -hcomo oacuterdenes compatibles) Este segundo ejemplo no lo veremos en clase

      52 Ejercicios

      Descarga el coacutedigo de ejemplo de getopt() de la documentacioacuten de glibc10 Lee elcoacutedigo compiacutelalo ejecuacutetalo para comprobar que admite las opciones de paraacutemetros POSIXTrata de entender el coacutedigo y antildeade maacutes opciones (por ejemplo una sin paraacutemetros y otra conparaacutemetros) Debes consultar la seccioacuten Using the getopt function de la documentacioacuten11

      para saber coacutemo funciona getopt queacute valores espera y queacute comportamiento tiene

      6 Variables de entorno

      61 Introduccioacuten y documentacioacuten

      Una variable de entorno es un objeto designado para contener informacioacuten usada poruna o maacutes aplicaciones La variables de entorno se asociacioacuten a toda la maacutequina pero tam-bieacuten a usuarios individuales Si utilizas bash puedes consultar las variables de entorno detu sesioacuten con el comando env Tambieacuten puedes consultar o modificar el valor de una varia-ble de forma individual

      $ env$ $ echo $LANGes_ESUTF-8$ export LANG=en_GBUTF-8

      7httppubsopengrouporgonlinepubs9699919799functionsgetopthtml8httpwwwgnuorgsoftwarelibcmanualhtml_nodeGetopthtml9Notas sobre portabilidad en httpwwwgnuorgsoftwaregnulibmanualgnulibhtml

      getopt10httpwwwgnuorgsoftwarelibcmanualhtml_nodeExample-of-Getopthtml11httpwwwgnuorgsoftwarelibcmanualhtml_nodeUsing-Getopthtml

      6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      62 Ejercicios

      Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

      7 Obtencioacuten de informacioacuten de un usuarioa

      71 Introduccioacuten y documentacioacuten

      En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

      En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

      POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

      72 Ejercicios

      Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

      12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

      httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

      9 Creacioacuten de procesos Fork y Exec 7

      8 Ejercicio resumen 1 (05 punto)

      Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

      Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

      Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

      Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

      1 Procesar opciones de entrada

      2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

      3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

      9 Creacioacuten de procesos Fork y Exec

      91 Introduccioacuten y documentacioacuten

      En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

      8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      pid=fork()

      case 0 hijo

      default padre

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

      resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

      $ find -name c -print | wc -l

      En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

      92 Ejercicios y ejemplos

      El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

      include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

      int main()

      pid_t rfrf = fork()switch (rf)

      15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

      9 Creacioacuten de procesos Fork y Exec 9

      case -1

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

      case 0printf (Soy el hijo mi PID es d y mi PPID es d n

      getpid() getppid())sleep (5)break

      defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

      d n getpid() rf)sleep (10)

      printf (Final de ejecucioacuten de d n getpid())exit (0)

      Un ejemplo de llamada a este coacutedigo seriacutea

      $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

      Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

      include ltunistdhgtinclude ltsyswaithgt

      int main()pid_t pidint status died

      18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

      10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      switch(pid=fork())case -1 printf(canrsquot forkn)

      exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

      exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

      En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

      include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

      int main()

      pid_t pidint status died

      char args[] = binls -r -t -l (char ) 0

      switch(pid=fork())case -1

      printf(canrsquot forkn)exit(-1)

      case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

      defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

      return(0)

      10 Sentildeales entre procesos 11

      10 Sentildeales entre procesos

      101 Introduccioacuten y documentacioacuten

      Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

      include ltsignalhgt

      sighandler_t signal(int signum sighandler_t handler)

      102 Ejercicios y ejemplos

      El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

      19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

      12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

      $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

      SIGKILL

      11 sockets POSIX

      111 Introduccioacuten y conceptos baacutesicos

      En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

      Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

      socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

      arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

      112 Algoritmo baacutesico Cliente-Servidor

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

      Servidor

      socket()

      connect()

      send()

      recv()

      closeSocket()

      Cliente

      socket()

      bind()

      listen()

      accept()

      recv()

      send()

      recv()

      closeSocket()

      El cliente enviacutea datos yel servidor los recive

      El servidor enviacutea datos y el cliente los recive

      El cliente manda un mensaje para finalizar la conexioacuten

      Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

      Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

      14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      113 Pasos de programacioacuten C en el lado Servidor

      Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

      Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

      Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

      Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

      Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

      114 Pasos de programacioacuten C en el lado Cliente

      Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

      Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

      Cerrar la comunicacioacuten por medio de close()

      12 Todo junto un servidor web baacutesico en C 15

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

      12 Todo junto un servidor web baacutesico en C

      121 Introduccioacuten y coacutedigo

      En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

      16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      Servidor

      socket()

      connect()

      send()

      recv()

      closeSocket()

      Cliente

      socket()

      bind()

      listen()

      accept()

      recv()

      send()

      recv()

      closeSocket()

      HTTP10 200 OKDatos

      El cliente manda un mensaje para finalizar la conexioacuten

      Diagrama de flujodel ejemplo de servidor web baacutesico

      startServer()

      while(1) fork()

      respond()

      fork()

      GET holahtml HTTP11

      La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

      El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

      Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

      122 Ejercicios

      Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

      $ ejemplo-webserver -p 8080 -r htdocs

      ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

      13 Ejercicio resumen 2 (1 punto) 17

      seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

      Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

      13 Ejercicio resumen 2 (1 punto)

      Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

      1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

      webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

      webServerLog(WS_LOG_ERROR Error en la conexioacuten)

      No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

      Figura 9 El Fary

      18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

      4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

      Para el segundo ejercicio una llamada similar a

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

      deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

      Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

      Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

      Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

      22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

      14 Trabajo futuro 19

      Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

      20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

      Referencias

      [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

      [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

      [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

      [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

      [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

      [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

      [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

      [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

      • 1 Introduccioacuten a POSIX
      • 2 Objetivos
      • 3 Entrega de praacutecticas
      • 4 Documentacioacuten de POSIX y las bibliotecas
      • 5 Procesado de liacutenea de comandos tipo POSIX
        • 51 Introduccioacuten y documentacioacuten
        • 52 Ejercicios
          • 6 Variables de entorno
            • 61 Introduccioacuten y documentacioacuten
            • 62 Ejercicios
              • 7 Obtencioacuten de informacioacuten de un usuarioa
                • 71 Introduccioacuten y documentacioacuten
                • 72 Ejercicios
                  • 8 Ejercicio resumen 1 (05 punto)
                  • 9 Creacioacuten de procesos Fork y Exec
                    • 91 Introduccioacuten y documentacioacuten
                    • 92 Ejercicios y ejemplos
                      • 10 Sentildeales entre procesos
                        • 101 Introduccioacuten y documentacioacuten
                        • 102 Ejercicios y ejemplos
                          • 11 sockets POSIX
                            • 111 Introduccioacuten y conceptos baacutesicos
                            • 112 Algoritmo baacutesico Cliente-Servidor
                            • 113 Pasos de programacioacuten C en el lado Servidor
                            • 114 Pasos de programacioacuten C en el lado Cliente
                              • 12 Todo junto un servidor web baacutesico en C
                                • 121 Introduccioacuten y coacutedigo
                                • 122 Ejercicios
                                  • 13 Ejercicio resumen 2 (1 punto)
                                  • 14 Trabajo futuro
                                  • Referencias

        4 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        cioacuten del API POSIX Algunas distribuciones de GNULinux como Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3 pero a efectos de programacioacuten no deberiacutea ha-ber diferencias

        2 Objetivos

        Conocer algunas rutinas POSIX y su implementacioacuten glibc

        Aprender a utilizar bibliotecas externas en nuestros programas

        Aprender coacutemo funcionan internamente algunas partes de GNULinux

        Mejorar la programacioacuten 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 praacutecticas

        Se pediraacute la entrega y defensa de algunos ejercicios resuacutemenes que integren varios de losconceptos y funciones estudiadas en clase Las praacutecticas deben realizarse a nivel individualy se utilizaraacuten mecanismos para comprobar que se han realizado y entendido

        4 Documentacioacuten de POSIX y las bibliotecas

        Documentacioacuten POSIX1-2008 Especificacioacuten del estaacutendar POSIX Dependiendo de la par-te que documente es maacutes o menos pedagoacutegica4

        Documentacioacuten GNU C Library Esta documentacioacuten incluye muchos de los conceptos queya habeacuteis trabajado en asignaturas de introduccioacuten a la programacioacuten o de sistemasoperativos Es una guiacutea completa de programacioacuten en el lenguaje C pero sobre to-do incluye muchas funciones que son esenciales para programar uacutetiles para ahorrartiempo trabajando o para garantizar la portabilidad del coacutedigo entre sistemas POSIX5

        5 Procesado de liacutenea de comandos tipo POSIX

        51 Introduccioacuten y documentacioacuten

        Los paraacutemetros que procesa un programa en sistemas POSIX deben seguir un estaacutendarde formato y respuesta esperada6 Un resumen de lo definido en el estaacutendar es lo siguiente

        3httpwwweglibcorghome4httppubsopengrouporgonlinepubs96999197995httpwwwgnuorgsoftwarelibcmanual6121 Utility Argument Syntax httppubsopengrouporgonlinepubs9699919799

        basedefsV1_chap12html

        6 Variables de entorno 5

        Una opcioacuten es un guioacuten rsquo-rsquo seguido de un caraacutecter alfanumeacuterico por ejemplo -o

        Una opcioacuten requiere un paraacutemetro que debe aparecer inmediatamente despueacutes de laopcioacuten por ejemplo para -o lo siguiente -o paraacutemetro o -oparaacutemetro

        Las opciones que no requieren paraacutemetros pueden agruparse detraacutes de un guioacuten porejemplo -lst es equivalente a -t -l -s

        Las opciones puede aparecer en cualquier orden asiacute -lst es equivalente a -tls

        Las opciones pueden aparecer muchas veces

        El paraacutemetro -- indica el fin de las opciones en cualquier caso

        La opcioacuten - a menudo se indica para representar alguna entrada estaacutendar

        La funcioacuten getopt()7 del estaacutendar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX1-2008 getopt() estaacute implementada en libc89 Puedes vercoacutedigo de ejemplo comentado en el fichero ejemplo-getoptc El fichero ejemplo-getoptlongccontiene un ejemplo de procesado de oacuterdenes al estilo de GNU (por ejemplo --help y -hcomo oacuterdenes compatibles) Este segundo ejemplo no lo veremos en clase

        52 Ejercicios

        Descarga el coacutedigo de ejemplo de getopt() de la documentacioacuten de glibc10 Lee elcoacutedigo compiacutelalo ejecuacutetalo para comprobar que admite las opciones de paraacutemetros POSIXTrata de entender el coacutedigo y antildeade maacutes opciones (por ejemplo una sin paraacutemetros y otra conparaacutemetros) Debes consultar la seccioacuten Using the getopt function de la documentacioacuten11

        para saber coacutemo funciona getopt queacute valores espera y queacute comportamiento tiene

        6 Variables de entorno

        61 Introduccioacuten y documentacioacuten

        Una variable de entorno es un objeto designado para contener informacioacuten usada poruna o maacutes aplicaciones La variables de entorno se asociacioacuten a toda la maacutequina pero tam-bieacuten a usuarios individuales Si utilizas bash puedes consultar las variables de entorno detu sesioacuten con el comando env Tambieacuten puedes consultar o modificar el valor de una varia-ble de forma individual

        $ env$ $ echo $LANGes_ESUTF-8$ export LANG=en_GBUTF-8

        7httppubsopengrouporgonlinepubs9699919799functionsgetopthtml8httpwwwgnuorgsoftwarelibcmanualhtml_nodeGetopthtml9Notas sobre portabilidad en httpwwwgnuorgsoftwaregnulibmanualgnulibhtml

        getopt10httpwwwgnuorgsoftwarelibcmanualhtml_nodeExample-of-Getopthtml11httpwwwgnuorgsoftwarelibcmanualhtml_nodeUsing-Getopthtml

        6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        62 Ejercicios

        Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

        7 Obtencioacuten de informacioacuten de un usuarioa

        71 Introduccioacuten y documentacioacuten

        En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

        En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

        POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

        72 Ejercicios

        Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

        12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

        httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

        9 Creacioacuten de procesos Fork y Exec 7

        8 Ejercicio resumen 1 (05 punto)

        Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

        Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

        Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

        Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

        1 Procesar opciones de entrada

        2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

        3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

        9 Creacioacuten de procesos Fork y Exec

        91 Introduccioacuten y documentacioacuten

        En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

        8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        pid=fork()

        case 0 hijo

        default padre

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

        resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

        $ find -name c -print | wc -l

        En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

        92 Ejercicios y ejemplos

        El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

        include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

        int main()

        pid_t rfrf = fork()switch (rf)

        15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

        9 Creacioacuten de procesos Fork y Exec 9

        case -1

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

        case 0printf (Soy el hijo mi PID es d y mi PPID es d n

        getpid() getppid())sleep (5)break

        defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

        d n getpid() rf)sleep (10)

        printf (Final de ejecucioacuten de d n getpid())exit (0)

        Un ejemplo de llamada a este coacutedigo seriacutea

        $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

        Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

        include ltunistdhgtinclude ltsyswaithgt

        int main()pid_t pidint status died

        18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

        10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        switch(pid=fork())case -1 printf(canrsquot forkn)

        exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

        exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

        En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

        include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

        int main()

        pid_t pidint status died

        char args[] = binls -r -t -l (char ) 0

        switch(pid=fork())case -1

        printf(canrsquot forkn)exit(-1)

        case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

        defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

        return(0)

        10 Sentildeales entre procesos 11

        10 Sentildeales entre procesos

        101 Introduccioacuten y documentacioacuten

        Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

        include ltsignalhgt

        sighandler_t signal(int signum sighandler_t handler)

        102 Ejercicios y ejemplos

        El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

        19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

        12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

        $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

        SIGKILL

        11 sockets POSIX

        111 Introduccioacuten y conceptos baacutesicos

        En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

        Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

        socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

        arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

        112 Algoritmo baacutesico Cliente-Servidor

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

        Servidor

        socket()

        connect()

        send()

        recv()

        closeSocket()

        Cliente

        socket()

        bind()

        listen()

        accept()

        recv()

        send()

        recv()

        closeSocket()

        El cliente enviacutea datos yel servidor los recive

        El servidor enviacutea datos y el cliente los recive

        El cliente manda un mensaje para finalizar la conexioacuten

        Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

        Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

        14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        113 Pasos de programacioacuten C en el lado Servidor

        Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

        Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

        Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

        Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

        Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

        114 Pasos de programacioacuten C en el lado Cliente

        Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

        Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

        Cerrar la comunicacioacuten por medio de close()

        12 Todo junto un servidor web baacutesico en C 15

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

        12 Todo junto un servidor web baacutesico en C

        121 Introduccioacuten y coacutedigo

        En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

        16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        Servidor

        socket()

        connect()

        send()

        recv()

        closeSocket()

        Cliente

        socket()

        bind()

        listen()

        accept()

        recv()

        send()

        recv()

        closeSocket()

        HTTP10 200 OKDatos

        El cliente manda un mensaje para finalizar la conexioacuten

        Diagrama de flujodel ejemplo de servidor web baacutesico

        startServer()

        while(1) fork()

        respond()

        fork()

        GET holahtml HTTP11

        La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

        El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

        Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

        122 Ejercicios

        Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

        $ ejemplo-webserver -p 8080 -r htdocs

        ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

        13 Ejercicio resumen 2 (1 punto) 17

        seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

        Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

        13 Ejercicio resumen 2 (1 punto)

        Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

        1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

        webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

        webServerLog(WS_LOG_ERROR Error en la conexioacuten)

        No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

        Figura 9 El Fary

        18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

        4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

        Para el segundo ejercicio una llamada similar a

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

        deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

        Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

        Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

        Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

        22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

        14 Trabajo futuro 19

        Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

        20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

        Referencias

        [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

        [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

        [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

        [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

        [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

        [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

        [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

        [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

        • 1 Introduccioacuten a POSIX
        • 2 Objetivos
        • 3 Entrega de praacutecticas
        • 4 Documentacioacuten de POSIX y las bibliotecas
        • 5 Procesado de liacutenea de comandos tipo POSIX
          • 51 Introduccioacuten y documentacioacuten
          • 52 Ejercicios
            • 6 Variables de entorno
              • 61 Introduccioacuten y documentacioacuten
              • 62 Ejercicios
                • 7 Obtencioacuten de informacioacuten de un usuarioa
                  • 71 Introduccioacuten y documentacioacuten
                  • 72 Ejercicios
                    • 8 Ejercicio resumen 1 (05 punto)
                    • 9 Creacioacuten de procesos Fork y Exec
                      • 91 Introduccioacuten y documentacioacuten
                      • 92 Ejercicios y ejemplos
                        • 10 Sentildeales entre procesos
                          • 101 Introduccioacuten y documentacioacuten
                          • 102 Ejercicios y ejemplos
                            • 11 sockets POSIX
                              • 111 Introduccioacuten y conceptos baacutesicos
                              • 112 Algoritmo baacutesico Cliente-Servidor
                              • 113 Pasos de programacioacuten C en el lado Servidor
                              • 114 Pasos de programacioacuten C en el lado Cliente
                                • 12 Todo junto un servidor web baacutesico en C
                                  • 121 Introduccioacuten y coacutedigo
                                  • 122 Ejercicios
                                    • 13 Ejercicio resumen 2 (1 punto)
                                    • 14 Trabajo futuro
                                    • Referencias

          6 Variables de entorno 5

          Una opcioacuten es un guioacuten rsquo-rsquo seguido de un caraacutecter alfanumeacuterico por ejemplo -o

          Una opcioacuten requiere un paraacutemetro que debe aparecer inmediatamente despueacutes de laopcioacuten por ejemplo para -o lo siguiente -o paraacutemetro o -oparaacutemetro

          Las opciones que no requieren paraacutemetros pueden agruparse detraacutes de un guioacuten porejemplo -lst es equivalente a -t -l -s

          Las opciones puede aparecer en cualquier orden asiacute -lst es equivalente a -tls

          Las opciones pueden aparecer muchas veces

          El paraacutemetro -- indica el fin de las opciones en cualquier caso

          La opcioacuten - a menudo se indica para representar alguna entrada estaacutendar

          La funcioacuten getopt()7 del estaacutendar ayuda a desarrollar el manejo de las opciones si-guiendo las directrices POSIX1-2008 getopt() estaacute implementada en libc89 Puedes vercoacutedigo de ejemplo comentado en el fichero ejemplo-getoptc El fichero ejemplo-getoptlongccontiene un ejemplo de procesado de oacuterdenes al estilo de GNU (por ejemplo --help y -hcomo oacuterdenes compatibles) Este segundo ejemplo no lo veremos en clase

          52 Ejercicios

          Descarga el coacutedigo de ejemplo de getopt() de la documentacioacuten de glibc10 Lee elcoacutedigo compiacutelalo ejecuacutetalo para comprobar que admite las opciones de paraacutemetros POSIXTrata de entender el coacutedigo y antildeade maacutes opciones (por ejemplo una sin paraacutemetros y otra conparaacutemetros) Debes consultar la seccioacuten Using the getopt function de la documentacioacuten11

          para saber coacutemo funciona getopt queacute valores espera y queacute comportamiento tiene

          6 Variables de entorno

          61 Introduccioacuten y documentacioacuten

          Una variable de entorno es un objeto designado para contener informacioacuten usada poruna o maacutes aplicaciones La variables de entorno se asociacioacuten a toda la maacutequina pero tam-bieacuten a usuarios individuales Si utilizas bash puedes consultar las variables de entorno detu sesioacuten con el comando env Tambieacuten puedes consultar o modificar el valor de una varia-ble de forma individual

          $ env$ $ echo $LANGes_ESUTF-8$ export LANG=en_GBUTF-8

          7httppubsopengrouporgonlinepubs9699919799functionsgetopthtml8httpwwwgnuorgsoftwarelibcmanualhtml_nodeGetopthtml9Notas sobre portabilidad en httpwwwgnuorgsoftwaregnulibmanualgnulibhtml

          getopt10httpwwwgnuorgsoftwarelibcmanualhtml_nodeExample-of-Getopthtml11httpwwwgnuorgsoftwarelibcmanualhtml_nodeUsing-Getopthtml

          6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          62 Ejercicios

          Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

          7 Obtencioacuten de informacioacuten de un usuarioa

          71 Introduccioacuten y documentacioacuten

          En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

          En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

          POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

          72 Ejercicios

          Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

          12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

          httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

          9 Creacioacuten de procesos Fork y Exec 7

          8 Ejercicio resumen 1 (05 punto)

          Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

          Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

          Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

          Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

          1 Procesar opciones de entrada

          2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

          3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

          9 Creacioacuten de procesos Fork y Exec

          91 Introduccioacuten y documentacioacuten

          En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

          8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          pid=fork()

          case 0 hijo

          default padre

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

          resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

          $ find -name c -print | wc -l

          En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

          92 Ejercicios y ejemplos

          El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

          include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

          int main()

          pid_t rfrf = fork()switch (rf)

          15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

          9 Creacioacuten de procesos Fork y Exec 9

          case -1

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

          case 0printf (Soy el hijo mi PID es d y mi PPID es d n

          getpid() getppid())sleep (5)break

          defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

          d n getpid() rf)sleep (10)

          printf (Final de ejecucioacuten de d n getpid())exit (0)

          Un ejemplo de llamada a este coacutedigo seriacutea

          $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

          Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

          include ltunistdhgtinclude ltsyswaithgt

          int main()pid_t pidint status died

          18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

          10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          switch(pid=fork())case -1 printf(canrsquot forkn)

          exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

          exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

          En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

          include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

          int main()

          pid_t pidint status died

          char args[] = binls -r -t -l (char ) 0

          switch(pid=fork())case -1

          printf(canrsquot forkn)exit(-1)

          case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

          defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

          return(0)

          10 Sentildeales entre procesos 11

          10 Sentildeales entre procesos

          101 Introduccioacuten y documentacioacuten

          Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

          include ltsignalhgt

          sighandler_t signal(int signum sighandler_t handler)

          102 Ejercicios y ejemplos

          El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

          19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

          12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

          $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

          SIGKILL

          11 sockets POSIX

          111 Introduccioacuten y conceptos baacutesicos

          En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

          Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

          socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

          arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

          112 Algoritmo baacutesico Cliente-Servidor

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

          Servidor

          socket()

          connect()

          send()

          recv()

          closeSocket()

          Cliente

          socket()

          bind()

          listen()

          accept()

          recv()

          send()

          recv()

          closeSocket()

          El cliente enviacutea datos yel servidor los recive

          El servidor enviacutea datos y el cliente los recive

          El cliente manda un mensaje para finalizar la conexioacuten

          Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

          Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

          14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          113 Pasos de programacioacuten C en el lado Servidor

          Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

          Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

          Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

          Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

          Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

          114 Pasos de programacioacuten C en el lado Cliente

          Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

          Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

          Cerrar la comunicacioacuten por medio de close()

          12 Todo junto un servidor web baacutesico en C 15

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

          12 Todo junto un servidor web baacutesico en C

          121 Introduccioacuten y coacutedigo

          En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

          16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          Servidor

          socket()

          connect()

          send()

          recv()

          closeSocket()

          Cliente

          socket()

          bind()

          listen()

          accept()

          recv()

          send()

          recv()

          closeSocket()

          HTTP10 200 OKDatos

          El cliente manda un mensaje para finalizar la conexioacuten

          Diagrama de flujodel ejemplo de servidor web baacutesico

          startServer()

          while(1) fork()

          respond()

          fork()

          GET holahtml HTTP11

          La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

          El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

          Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

          122 Ejercicios

          Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

          $ ejemplo-webserver -p 8080 -r htdocs

          ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

          13 Ejercicio resumen 2 (1 punto) 17

          seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

          Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

          13 Ejercicio resumen 2 (1 punto)

          Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

          1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

          webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

          webServerLog(WS_LOG_ERROR Error en la conexioacuten)

          No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

          Figura 9 El Fary

          18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

          4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

          Para el segundo ejercicio una llamada similar a

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

          deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

          Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

          Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

          Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

          22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

          14 Trabajo futuro 19

          Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

          20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

          Referencias

          [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

          [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

          [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

          [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

          [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

          [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

          [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

          [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

          • 1 Introduccioacuten a POSIX
          • 2 Objetivos
          • 3 Entrega de praacutecticas
          • 4 Documentacioacuten de POSIX y las bibliotecas
          • 5 Procesado de liacutenea de comandos tipo POSIX
            • 51 Introduccioacuten y documentacioacuten
            • 52 Ejercicios
              • 6 Variables de entorno
                • 61 Introduccioacuten y documentacioacuten
                • 62 Ejercicios
                  • 7 Obtencioacuten de informacioacuten de un usuarioa
                    • 71 Introduccioacuten y documentacioacuten
                    • 72 Ejercicios
                      • 8 Ejercicio resumen 1 (05 punto)
                      • 9 Creacioacuten de procesos Fork y Exec
                        • 91 Introduccioacuten y documentacioacuten
                        • 92 Ejercicios y ejemplos
                          • 10 Sentildeales entre procesos
                            • 101 Introduccioacuten y documentacioacuten
                            • 102 Ejercicios y ejemplos
                              • 11 sockets POSIX
                                • 111 Introduccioacuten y conceptos baacutesicos
                                • 112 Algoritmo baacutesico Cliente-Servidor
                                • 113 Pasos de programacioacuten C en el lado Servidor
                                • 114 Pasos de programacioacuten C en el lado Cliente
                                  • 12 Todo junto un servidor web baacutesico en C
                                    • 121 Introduccioacuten y coacutedigo
                                    • 122 Ejercicios
                                      • 13 Ejercicio resumen 2 (1 punto)
                                      • 14 Trabajo futuro
                                      • Referencias

            6 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            62 Ejercicios

            Utilizando la funcioacuten getenv()12 haz un programa que dependiendo del idioma de lasesioacuten de usuario imprima un mensaje con su carpeta personal en castellano o en ingleacutesPuedes ver coacutedigo de ejemplo en el fichero ejemplo-getenvc

            7 Obtencioacuten de informacioacuten de un usuarioa

            71 Introduccioacuten y documentacioacuten

            En los sistemas operativos la base de datos de usuarios puede ser local yo remota Porejemplo en GNULinux puedes ver los usuarios y grupos locales en los ficheros etcpasswdy etcgroup Si los usuarios no son locales normalmente se encuentran en una maacutequinaremota a la que se accede por un protocolo especiacutefico Algunos ejemplos son el servicio deinformacioacuten 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 estaacutendar para autenticar usuarios tanto en sistemas Unix o GNULinux comoen sistemas Windows

            En el caso de GNULinux la autenticacioacuten de usuarios la realizan los moacutedulos de au-tenticacioacuten PAM (Pluggable Authentication Module) PAM es un mecanismo de autenticacioacutenflexible que permite abstraer las aplicaciones del proceso de identificacioacuten La buacutesqueda desu informacioacuten 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 etcpasswd etcgroup etchosts LDAP etc

            POSIX presenta una interfaz para el acceso a la informacioacuten de usuarios que abstrae alprogramador de doacutende se encuentran los usuarios (en bases de datos locales yo remotascon distintos formatos etc) Por ejemplo la llamada getpwuid() devuelve una estructuracon informacioacuten de un usuario El sistema POSIX se encarga de intercambiar informacioacutencon NSS para conseguir la informacioacuten del usuario NSS leeraacute ficheros en el disco duro orealizaraacute consultas a traveacutes de la red para conseguir esa informacioacuten

            72 Ejercicios

            Puedes ver las funciones y estructuras de acceso a la informacioacuten de usuariosas y gru-pos en los siguientes ficheros de cabecera usrincludepwdh usrincludegrphLa funcioacuten getpwnam()13 permite obtener informacioacuten de un usuarioa Mira el programade ejemplo de getpwnam() y ampliacutealo para utilizar getgrgid()14 para obtener el nombredel grupo del usuario a traveacutes del identificador del grupo Puedes ver coacutedigo de ejemplo enel fichero ejemplo-infousuarioc

            12httppubsopengrouporgonlinepubs009604599functionsgetenvhtml13httppubsopengrouporgonlinepubs009604599functionsgetpwnamhtml

            httpwwwgnuorgsoftwarelibcmanualhtml_nodeUser-Databasehtml14httpwwwgnuorgsoftwarelibcmanualhtml_nodeGroup-Databasehtml

            9 Creacioacuten de procesos Fork y Exec 7

            8 Ejercicio resumen 1 (05 punto)

            Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

            Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

            Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

            Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

            1 Procesar opciones de entrada

            2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

            3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

            9 Creacioacuten de procesos Fork y Exec

            91 Introduccioacuten y documentacioacuten

            En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

            8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            pid=fork()

            case 0 hijo

            default padre

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

            resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

            $ find -name c -print | wc -l

            En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

            92 Ejercicios y ejemplos

            El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

            include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

            int main()

            pid_t rfrf = fork()switch (rf)

            15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

            9 Creacioacuten de procesos Fork y Exec 9

            case -1

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

            case 0printf (Soy el hijo mi PID es d y mi PPID es d n

            getpid() getppid())sleep (5)break

            defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

            d n getpid() rf)sleep (10)

            printf (Final de ejecucioacuten de d n getpid())exit (0)

            Un ejemplo de llamada a este coacutedigo seriacutea

            $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

            Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

            include ltunistdhgtinclude ltsyswaithgt

            int main()pid_t pidint status died

            18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

            10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            switch(pid=fork())case -1 printf(canrsquot forkn)

            exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

            exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

            En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

            include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

            int main()

            pid_t pidint status died

            char args[] = binls -r -t -l (char ) 0

            switch(pid=fork())case -1

            printf(canrsquot forkn)exit(-1)

            case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

            defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

            return(0)

            10 Sentildeales entre procesos 11

            10 Sentildeales entre procesos

            101 Introduccioacuten y documentacioacuten

            Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

            include ltsignalhgt

            sighandler_t signal(int signum sighandler_t handler)

            102 Ejercicios y ejemplos

            El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

            19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

            12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

            $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

            SIGKILL

            11 sockets POSIX

            111 Introduccioacuten y conceptos baacutesicos

            En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

            Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

            socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

            arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

            112 Algoritmo baacutesico Cliente-Servidor

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

            Servidor

            socket()

            connect()

            send()

            recv()

            closeSocket()

            Cliente

            socket()

            bind()

            listen()

            accept()

            recv()

            send()

            recv()

            closeSocket()

            El cliente enviacutea datos yel servidor los recive

            El servidor enviacutea datos y el cliente los recive

            El cliente manda un mensaje para finalizar la conexioacuten

            Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

            Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

            14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            113 Pasos de programacioacuten C en el lado Servidor

            Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

            Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

            Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

            Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

            Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

            114 Pasos de programacioacuten C en el lado Cliente

            Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

            Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

            Cerrar la comunicacioacuten por medio de close()

            12 Todo junto un servidor web baacutesico en C 15

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

            12 Todo junto un servidor web baacutesico en C

            121 Introduccioacuten y coacutedigo

            En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

            16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            Servidor

            socket()

            connect()

            send()

            recv()

            closeSocket()

            Cliente

            socket()

            bind()

            listen()

            accept()

            recv()

            send()

            recv()

            closeSocket()

            HTTP10 200 OKDatos

            El cliente manda un mensaje para finalizar la conexioacuten

            Diagrama de flujodel ejemplo de servidor web baacutesico

            startServer()

            while(1) fork()

            respond()

            fork()

            GET holahtml HTTP11

            La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

            El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

            Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

            122 Ejercicios

            Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

            $ ejemplo-webserver -p 8080 -r htdocs

            ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

            13 Ejercicio resumen 2 (1 punto) 17

            seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

            Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

            13 Ejercicio resumen 2 (1 punto)

            Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

            1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

            webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

            webServerLog(WS_LOG_ERROR Error en la conexioacuten)

            No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

            Figura 9 El Fary

            18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

            4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

            Para el segundo ejercicio una llamada similar a

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

            deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

            Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

            Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

            Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

            22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

            14 Trabajo futuro 19

            Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

            20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

            Referencias

            [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

            [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

            [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

            [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

            [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

            [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

            [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

            [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

            • 1 Introduccioacuten a POSIX
            • 2 Objetivos
            • 3 Entrega de praacutecticas
            • 4 Documentacioacuten de POSIX y las bibliotecas
            • 5 Procesado de liacutenea de comandos tipo POSIX
              • 51 Introduccioacuten y documentacioacuten
              • 52 Ejercicios
                • 6 Variables de entorno
                  • 61 Introduccioacuten y documentacioacuten
                  • 62 Ejercicios
                    • 7 Obtencioacuten de informacioacuten de un usuarioa
                      • 71 Introduccioacuten y documentacioacuten
                      • 72 Ejercicios
                        • 8 Ejercicio resumen 1 (05 punto)
                        • 9 Creacioacuten de procesos Fork y Exec
                          • 91 Introduccioacuten y documentacioacuten
                          • 92 Ejercicios y ejemplos
                            • 10 Sentildeales entre procesos
                              • 101 Introduccioacuten y documentacioacuten
                              • 102 Ejercicios y ejemplos
                                • 11 sockets POSIX
                                  • 111 Introduccioacuten y conceptos baacutesicos
                                  • 112 Algoritmo baacutesico Cliente-Servidor
                                  • 113 Pasos de programacioacuten C en el lado Servidor
                                  • 114 Pasos de programacioacuten C en el lado Cliente
                                    • 12 Todo junto un servidor web baacutesico en C
                                      • 121 Introduccioacuten y coacutedigo
                                      • 122 Ejercicios
                                        • 13 Ejercicio resumen 2 (1 punto)
                                        • 14 Trabajo futuro
                                        • Referencias

              9 Creacioacuten de procesos Fork y Exec 7

              8 Ejercicio resumen 1 (05 punto)

              Realizar un programa que obtenga e imprima la informacioacuten de un usuario (todos loscampos de la estructura passwd) pasado por el paraacutemetro -u Si ademaacutes se le pasa la opcioacuten-g deberaacute buscar e imprimir la informacioacuten del grupo del usuario (nuacutemero ID del grupo ynombre)

              Si se le pasa la opcioacuten -e imprimiraacute el mensaje en castellano y la opcioacuten -s hace que loimprima en ingleacutes Si no se le pasa ni -e ni -s se miraraacute la variable de entorno LANG paramostrar la informacioacuten Por ejemplo las siguientes llamadas seriacutean vaacutelidas

              Obtener la informacioacuten de un usuario usando el idioma configurado en LANG$ infousuario -u i02samoj Obtener la informacioacuten de un usuario forzando el idioma en castellano$ infousuario -u i02samoj -e Obtener la informacioacuten de un usuario antildeadiendo la informacioacuten de su grupo principal e imprimiendo todo en ingleacutes$ 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 coacutemo controlar quese pasa el paraacutemetro de una opcioacuten en el ejemplo-getoptc)

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

              Sugerencia empezar por el coacutedigo de ejemplo ejemplo-getoptc Primero debe pro-cesarse la entrada de comandos para asegurarse que no falta ninguna opcioacuten esencial (porejemplo el nombre de usuario) Despueacutes debe ir la loacutegica del programa dependiendo de lasopciones que se hayan reconocido Se pueden hacer funciones para simplificar la funcioacutenmain Por ejemplo una funcioacuten para imprimir la informacioacuten del usuario en castellanoin-gleacutes a la que se le pase la estructura struct passwd y una opcioacuten Una sugerencia para elesquema general puede ser

              1 Procesar opciones de entrada

              2 Usar la variable de entorno LANG si las ldquoflagsrdquo de las opciones -e o -s estaacuten a cero

              3 Llamar a una funcioacuten que imprima la informacioacuten de un usuario en ingleacutes o castellanocon las opciones (login grupo sino idioma)

              9 Creacioacuten de procesos Fork y Exec

              91 Introduccioacuten y documentacioacuten

              En general en sistemas operativos y lenguajes de programacioacuten se llama bifurcacioacuten ofork a la creacioacuten de un subproceso copia del proceso que llama a la funcioacuten El subprocesocreado o ldquoproceso hijordquo proviene del proceso originario o ldquoproceso padrerdquo Los procesos

              8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              pid=fork()

              case 0 hijo

              default padre

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

              resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

              $ find -name c -print | wc -l

              En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

              92 Ejercicios y ejemplos

              El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

              include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

              int main()

              pid_t rfrf = fork()switch (rf)

              15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

              9 Creacioacuten de procesos Fork y Exec 9

              case -1

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

              case 0printf (Soy el hijo mi PID es d y mi PPID es d n

              getpid() getppid())sleep (5)break

              defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

              d n getpid() rf)sleep (10)

              printf (Final de ejecucioacuten de d n getpid())exit (0)

              Un ejemplo de llamada a este coacutedigo seriacutea

              $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

              Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

              include ltunistdhgtinclude ltsyswaithgt

              int main()pid_t pidint status died

              18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

              10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              switch(pid=fork())case -1 printf(canrsquot forkn)

              exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

              exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

              En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

              include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

              int main()

              pid_t pidint status died

              char args[] = binls -r -t -l (char ) 0

              switch(pid=fork())case -1

              printf(canrsquot forkn)exit(-1)

              case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

              defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

              return(0)

              10 Sentildeales entre procesos 11

              10 Sentildeales entre procesos

              101 Introduccioacuten y documentacioacuten

              Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

              include ltsignalhgt

              sighandler_t signal(int signum sighandler_t handler)

              102 Ejercicios y ejemplos

              El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

              19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

              12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

              $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

              SIGKILL

              11 sockets POSIX

              111 Introduccioacuten y conceptos baacutesicos

              En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

              Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

              socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

              arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

              112 Algoritmo baacutesico Cliente-Servidor

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

              Servidor

              socket()

              connect()

              send()

              recv()

              closeSocket()

              Cliente

              socket()

              bind()

              listen()

              accept()

              recv()

              send()

              recv()

              closeSocket()

              El cliente enviacutea datos yel servidor los recive

              El servidor enviacutea datos y el cliente los recive

              El cliente manda un mensaje para finalizar la conexioacuten

              Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

              Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

              14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              113 Pasos de programacioacuten C en el lado Servidor

              Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

              Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

              Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

              Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

              Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

              114 Pasos de programacioacuten C en el lado Cliente

              Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

              Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

              Cerrar la comunicacioacuten por medio de close()

              12 Todo junto un servidor web baacutesico en C 15

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

              12 Todo junto un servidor web baacutesico en C

              121 Introduccioacuten y coacutedigo

              En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

              16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              Servidor

              socket()

              connect()

              send()

              recv()

              closeSocket()

              Cliente

              socket()

              bind()

              listen()

              accept()

              recv()

              send()

              recv()

              closeSocket()

              HTTP10 200 OKDatos

              El cliente manda un mensaje para finalizar la conexioacuten

              Diagrama de flujodel ejemplo de servidor web baacutesico

              startServer()

              while(1) fork()

              respond()

              fork()

              GET holahtml HTTP11

              La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

              El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

              Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

              122 Ejercicios

              Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

              $ ejemplo-webserver -p 8080 -r htdocs

              ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

              13 Ejercicio resumen 2 (1 punto) 17

              seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

              Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

              13 Ejercicio resumen 2 (1 punto)

              Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

              1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

              webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

              webServerLog(WS_LOG_ERROR Error en la conexioacuten)

              No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

              Figura 9 El Fary

              18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

              4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

              Para el segundo ejercicio una llamada similar a

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

              deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

              Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

              Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

              Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

              22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

              14 Trabajo futuro 19

              Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

              20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

              Referencias

              [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

              [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

              [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

              [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

              [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

              [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

              [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

              [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

              • 1 Introduccioacuten a POSIX
              • 2 Objetivos
              • 3 Entrega de praacutecticas
              • 4 Documentacioacuten de POSIX y las bibliotecas
              • 5 Procesado de liacutenea de comandos tipo POSIX
                • 51 Introduccioacuten y documentacioacuten
                • 52 Ejercicios
                  • 6 Variables de entorno
                    • 61 Introduccioacuten y documentacioacuten
                    • 62 Ejercicios
                      • 7 Obtencioacuten de informacioacuten de un usuarioa
                        • 71 Introduccioacuten y documentacioacuten
                        • 72 Ejercicios
                          • 8 Ejercicio resumen 1 (05 punto)
                          • 9 Creacioacuten de procesos Fork y Exec
                            • 91 Introduccioacuten y documentacioacuten
                            • 92 Ejercicios y ejemplos
                              • 10 Sentildeales entre procesos
                                • 101 Introduccioacuten y documentacioacuten
                                • 102 Ejercicios y ejemplos
                                  • 11 sockets POSIX
                                    • 111 Introduccioacuten y conceptos baacutesicos
                                    • 112 Algoritmo baacutesico Cliente-Servidor
                                    • 113 Pasos de programacioacuten C en el lado Servidor
                                    • 114 Pasos de programacioacuten C en el lado Cliente
                                      • 12 Todo junto un servidor web baacutesico en C
                                        • 121 Introduccioacuten y coacutedigo
                                        • 122 Ejercicios
                                          • 13 Ejercicio resumen 2 (1 punto)
                                          • 14 Trabajo futuro
                                          • Referencias

                8 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                pid=fork()

                case 0 hijo

                default padre

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

                resultantes son ideacutenticos salvo que tienen distinto nuacutemero de proceso (PID)15 En UNIXotra forma de crear subprocesos es utilizar tuberiacuteas o pipes las cuaacuteles son esenciales para lacomunicacioacuten inter-procesos por ejemplo

                $ find -name c -print | wc -l

                En C se crea un subproceso con llamando a la funcioacuten fork()16 Tienes un pequentildeomanual y mucho coacutedigo de ejemplo en [6] Puedes ver un coacutedigo 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 enqueacute sucede internamente a nivel del sistema operativo Despueacutes de una llamada exitosa afork habraacute dos copias del coacutedigo original ejecutaacutendose a la vez En el proceso original elvalor devuelto de fork seraacute el identificador del proceso hijo En cambio en el proceso hijoel valor devuelto por fork seraacute 0

                92 Ejercicios y ejemplos

                El listado siguiente (ejemplo-forkc) es un ejemplo de uso de fork que controla queacutetipo de proceso es el que ejecuta el coacutedigo utilizando el valor devuelto por la funcioacuten asiacute co-mo otras funciones POSIX para obtener informacioacuten de los procesos (puedes ver un esquemade las subprocesos creados en la Figura 4)

                include ltunistdhgtinclude ltstdiohgtinclude ltstdlibhgt

                int main()

                pid_t rfrf = fork()switch (rf)

                15httpwwwgnuorgsoftwarelibcmanualhtml_nodeProcesseshtml16httppubsopengrouporgonlinepubs969991979917httpeswikipediaorgwikiBifurcaciC3B3n_28sistema_operativo29

                9 Creacioacuten de procesos Fork y Exec 9

                case -1

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

                case 0printf (Soy el hijo mi PID es d y mi PPID es d n

                getpid() getppid())sleep (5)break

                defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

                d n getpid() rf)sleep (10)

                printf (Final de ejecucioacuten de d n getpid())exit (0)

                Un ejemplo de llamada a este coacutedigo seriacutea

                $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

                Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

                include ltunistdhgtinclude ltsyswaithgt

                int main()pid_t pidint status died

                18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

                10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                switch(pid=fork())case -1 printf(canrsquot forkn)

                exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

                exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

                En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

                include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

                int main()

                pid_t pidint status died

                char args[] = binls -r -t -l (char ) 0

                switch(pid=fork())case -1

                printf(canrsquot forkn)exit(-1)

                case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

                defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

                return(0)

                10 Sentildeales entre procesos 11

                10 Sentildeales entre procesos

                101 Introduccioacuten y documentacioacuten

                Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

                include ltsignalhgt

                sighandler_t signal(int signum sighandler_t handler)

                102 Ejercicios y ejemplos

                El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

                19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

                12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

                $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

                SIGKILL

                11 sockets POSIX

                111 Introduccioacuten y conceptos baacutesicos

                En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

                Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

                socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

                arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                112 Algoritmo baacutesico Cliente-Servidor

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

                Servidor

                socket()

                connect()

                send()

                recv()

                closeSocket()

                Cliente

                socket()

                bind()

                listen()

                accept()

                recv()

                send()

                recv()

                closeSocket()

                El cliente enviacutea datos yel servidor los recive

                El servidor enviacutea datos y el cliente los recive

                El cliente manda un mensaje para finalizar la conexioacuten

                Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                113 Pasos de programacioacuten C en el lado Servidor

                Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                114 Pasos de programacioacuten C en el lado Cliente

                Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                Cerrar la comunicacioacuten por medio de close()

                12 Todo junto un servidor web baacutesico en C 15

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

                12 Todo junto un servidor web baacutesico en C

                121 Introduccioacuten y coacutedigo

                En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                Servidor

                socket()

                connect()

                send()

                recv()

                closeSocket()

                Cliente

                socket()

                bind()

                listen()

                accept()

                recv()

                send()

                recv()

                closeSocket()

                HTTP10 200 OKDatos

                El cliente manda un mensaje para finalizar la conexioacuten

                Diagrama de flujodel ejemplo de servidor web baacutesico

                startServer()

                while(1) fork()

                respond()

                fork()

                GET holahtml HTTP11

                La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                122 Ejercicios

                Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                $ ejemplo-webserver -p 8080 -r htdocs

                ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                13 Ejercicio resumen 2 (1 punto) 17

                seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                13 Ejercicio resumen 2 (1 punto)

                Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                Figura 9 El Fary

                18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                Para el segundo ejercicio una llamada similar a

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

                deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                14 Trabajo futuro 19

                Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                Referencias

                [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                • 1 Introduccioacuten a POSIX
                • 2 Objetivos
                • 3 Entrega de praacutecticas
                • 4 Documentacioacuten de POSIX y las bibliotecas
                • 5 Procesado de liacutenea de comandos tipo POSIX
                  • 51 Introduccioacuten y documentacioacuten
                  • 52 Ejercicios
                    • 6 Variables de entorno
                      • 61 Introduccioacuten y documentacioacuten
                      • 62 Ejercicios
                        • 7 Obtencioacuten de informacioacuten de un usuarioa
                          • 71 Introduccioacuten y documentacioacuten
                          • 72 Ejercicios
                            • 8 Ejercicio resumen 1 (05 punto)
                            • 9 Creacioacuten de procesos Fork y Exec
                              • 91 Introduccioacuten y documentacioacuten
                              • 92 Ejercicios y ejemplos
                                • 10 Sentildeales entre procesos
                                  • 101 Introduccioacuten y documentacioacuten
                                  • 102 Ejercicios y ejemplos
                                    • 11 sockets POSIX
                                      • 111 Introduccioacuten y conceptos baacutesicos
                                      • 112 Algoritmo baacutesico Cliente-Servidor
                                      • 113 Pasos de programacioacuten C en el lado Servidor
                                      • 114 Pasos de programacioacuten C en el lado Cliente
                                        • 12 Todo junto un servidor web baacutesico en C
                                          • 121 Introduccioacuten y coacutedigo
                                          • 122 Ejercicios
                                            • 13 Ejercicio resumen 2 (1 punto)
                                            • 14 Trabajo futuro
                                            • Referencias

                  9 Creacioacuten de procesos Fork y Exec 9

                  case -1

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

                  case 0printf (Soy el hijo mi PID es d y mi PPID es d n

                  getpid() getppid())sleep (5)break

                  defaultprintf (Soy el padre mi PID es d y el PID de mi hijo es

                  d n getpid() rf)sleep (10)

                  printf (Final de ejecucioacuten de d n getpid())exit (0)

                  Un ejemplo de llamada a este coacutedigo seriacutea

                  $ 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 ejecucioacuten de 23456Final de ejecucioacuten 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 ejecucioacuten de 23437$ Final de ejecucioacuten de 23438

                  Si quisieacuteramos que el proceso padre esperase a que el proceso (o los procesos) hijos ter-minasen debemos utilizar la funcioacuten wait18 El valor devuelto por la funcioacuten wait es elPID del proceso hijo que se estaacute esperando que termine si se le ha pasado un PID comoargumento Si soacutelo se le pasa ampstatus wait() espera a que terminen todos los procesoshijos y devuelve el PID del uacuteltimo proceso en terminar Un ejemplo

                  include ltunistdhgtinclude ltsyswaithgt

                  int main()pid_t pidint status died

                  18wwwgnuorgsoftwarelibcmanualhtml_nodeProcess-Completionhtml

                  10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  switch(pid=fork())case -1 printf(canrsquot forkn)

                  exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

                  exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

                  En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

                  include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

                  int main()

                  pid_t pidint status died

                  char args[] = binls -r -t -l (char ) 0

                  switch(pid=fork())case -1

                  printf(canrsquot forkn)exit(-1)

                  case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

                  defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

                  return(0)

                  10 Sentildeales entre procesos 11

                  10 Sentildeales entre procesos

                  101 Introduccioacuten y documentacioacuten

                  Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

                  include ltsignalhgt

                  sighandler_t signal(int signum sighandler_t handler)

                  102 Ejercicios y ejemplos

                  El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

                  19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

                  12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

                  $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

                  SIGKILL

                  11 sockets POSIX

                  111 Introduccioacuten y conceptos baacutesicos

                  En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

                  Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

                  socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

                  arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                  112 Algoritmo baacutesico Cliente-Servidor

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

                  Servidor

                  socket()

                  connect()

                  send()

                  recv()

                  closeSocket()

                  Cliente

                  socket()

                  bind()

                  listen()

                  accept()

                  recv()

                  send()

                  recv()

                  closeSocket()

                  El cliente enviacutea datos yel servidor los recive

                  El servidor enviacutea datos y el cliente los recive

                  El cliente manda un mensaje para finalizar la conexioacuten

                  Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                  Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                  14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  113 Pasos de programacioacuten C en el lado Servidor

                  Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                  Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                  Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                  Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                  Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                  114 Pasos de programacioacuten C en el lado Cliente

                  Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                  Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                  Cerrar la comunicacioacuten por medio de close()

                  12 Todo junto un servidor web baacutesico en C 15

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

                  12 Todo junto un servidor web baacutesico en C

                  121 Introduccioacuten y coacutedigo

                  En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                  16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  Servidor

                  socket()

                  connect()

                  send()

                  recv()

                  closeSocket()

                  Cliente

                  socket()

                  bind()

                  listen()

                  accept()

                  recv()

                  send()

                  recv()

                  closeSocket()

                  HTTP10 200 OKDatos

                  El cliente manda un mensaje para finalizar la conexioacuten

                  Diagrama de flujodel ejemplo de servidor web baacutesico

                  startServer()

                  while(1) fork()

                  respond()

                  fork()

                  GET holahtml HTTP11

                  La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                  El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                  Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                  122 Ejercicios

                  Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                  $ ejemplo-webserver -p 8080 -r htdocs

                  ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                  13 Ejercicio resumen 2 (1 punto) 17

                  seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                  Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                  13 Ejercicio resumen 2 (1 punto)

                  Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                  1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                  webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                  webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                  No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                  Figura 9 El Fary

                  18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                  4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                  Para el segundo ejercicio una llamada similar a

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

                  deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                  Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                  Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                  Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                  22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                  14 Trabajo futuro 19

                  Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                  20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                  Referencias

                  [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                  [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                  [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                  [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                  [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                  [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                  [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                  [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                  • 1 Introduccioacuten a POSIX
                  • 2 Objetivos
                  • 3 Entrega de praacutecticas
                  • 4 Documentacioacuten de POSIX y las bibliotecas
                  • 5 Procesado de liacutenea de comandos tipo POSIX
                    • 51 Introduccioacuten y documentacioacuten
                    • 52 Ejercicios
                      • 6 Variables de entorno
                        • 61 Introduccioacuten y documentacioacuten
                        • 62 Ejercicios
                          • 7 Obtencioacuten de informacioacuten de un usuarioa
                            • 71 Introduccioacuten y documentacioacuten
                            • 72 Ejercicios
                              • 8 Ejercicio resumen 1 (05 punto)
                              • 9 Creacioacuten de procesos Fork y Exec
                                • 91 Introduccioacuten y documentacioacuten
                                • 92 Ejercicios y ejemplos
                                  • 10 Sentildeales entre procesos
                                    • 101 Introduccioacuten y documentacioacuten
                                    • 102 Ejercicios y ejemplos
                                      • 11 sockets POSIX
                                        • 111 Introduccioacuten y conceptos baacutesicos
                                        • 112 Algoritmo baacutesico Cliente-Servidor
                                        • 113 Pasos de programacioacuten C en el lado Servidor
                                        • 114 Pasos de programacioacuten C en el lado Cliente
                                          • 12 Todo junto un servidor web baacutesico en C
                                            • 121 Introduccioacuten y coacutedigo
                                            • 122 Ejercicios
                                              • 13 Ejercicio resumen 2 (1 punto)
                                              • 14 Trabajo futuro
                                              • Referencias

                    10 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    switch(pid=fork())case -1 printf(canrsquot forkn)

                    exit(-1)case 0 sleep(2) coacutedigo que ejecuta el hijo

                    exit(3)default died= wait(ampstatus) coacutedigo que ejecuta el padre

                    En ocasiones puede interesar ejecutar un programa distinto no diferentes partes de eacutel 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 funcioacuten 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 coacutedigo deejemplo

                    include ltunistdhgtinclude ltsyswaithgtinclude ltstdiohgtinclude ltstdlibhgt

                    int main()

                    pid_t pidint status died

                    char args[] = binls -r -t -l (char ) 0

                    switch(pid=fork())case -1

                    printf(canrsquot forkn)exit(-1)

                    case 0 printf(childn) coacutedigo que ejecuta el hijoexecv(binls args)

                    defaultdied= wait(ampstatus) coacutedigo que ejecuta el padre

                    return(0)

                    10 Sentildeales entre procesos 11

                    10 Sentildeales entre procesos

                    101 Introduccioacuten y documentacioacuten

                    Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

                    include ltsignalhgt

                    sighandler_t signal(int signum sighandler_t handler)

                    102 Ejercicios y ejemplos

                    El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

                    19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

                    12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

                    $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

                    SIGKILL

                    11 sockets POSIX

                    111 Introduccioacuten y conceptos baacutesicos

                    En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

                    Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

                    socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

                    arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                    112 Algoritmo baacutesico Cliente-Servidor

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

                    Servidor

                    socket()

                    connect()

                    send()

                    recv()

                    closeSocket()

                    Cliente

                    socket()

                    bind()

                    listen()

                    accept()

                    recv()

                    send()

                    recv()

                    closeSocket()

                    El cliente enviacutea datos yel servidor los recive

                    El servidor enviacutea datos y el cliente los recive

                    El cliente manda un mensaje para finalizar la conexioacuten

                    Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                    Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                    14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    113 Pasos de programacioacuten C en el lado Servidor

                    Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                    Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                    Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                    Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                    Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                    114 Pasos de programacioacuten C en el lado Cliente

                    Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                    Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                    Cerrar la comunicacioacuten por medio de close()

                    12 Todo junto un servidor web baacutesico en C 15

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

                    12 Todo junto un servidor web baacutesico en C

                    121 Introduccioacuten y coacutedigo

                    En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                    16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    Servidor

                    socket()

                    connect()

                    send()

                    recv()

                    closeSocket()

                    Cliente

                    socket()

                    bind()

                    listen()

                    accept()

                    recv()

                    send()

                    recv()

                    closeSocket()

                    HTTP10 200 OKDatos

                    El cliente manda un mensaje para finalizar la conexioacuten

                    Diagrama de flujodel ejemplo de servidor web baacutesico

                    startServer()

                    while(1) fork()

                    respond()

                    fork()

                    GET holahtml HTTP11

                    La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                    El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                    Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                    122 Ejercicios

                    Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                    $ ejemplo-webserver -p 8080 -r htdocs

                    ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                    13 Ejercicio resumen 2 (1 punto) 17

                    seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                    Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                    13 Ejercicio resumen 2 (1 punto)

                    Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                    1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                    webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                    webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                    No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                    Figura 9 El Fary

                    18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                    4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                    Para el segundo ejercicio una llamada similar a

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

                    deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                    Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                    Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                    Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                    22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                    14 Trabajo futuro 19

                    Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                    20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                    Referencias

                    [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                    [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                    [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                    [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                    [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                    [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                    [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                    [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                    • 1 Introduccioacuten a POSIX
                    • 2 Objetivos
                    • 3 Entrega de praacutecticas
                    • 4 Documentacioacuten de POSIX y las bibliotecas
                    • 5 Procesado de liacutenea de comandos tipo POSIX
                      • 51 Introduccioacuten y documentacioacuten
                      • 52 Ejercicios
                        • 6 Variables de entorno
                          • 61 Introduccioacuten y documentacioacuten
                          • 62 Ejercicios
                            • 7 Obtencioacuten de informacioacuten de un usuarioa
                              • 71 Introduccioacuten y documentacioacuten
                              • 72 Ejercicios
                                • 8 Ejercicio resumen 1 (05 punto)
                                • 9 Creacioacuten de procesos Fork y Exec
                                  • 91 Introduccioacuten y documentacioacuten
                                  • 92 Ejercicios y ejemplos
                                    • 10 Sentildeales entre procesos
                                      • 101 Introduccioacuten y documentacioacuten
                                      • 102 Ejercicios y ejemplos
                                        • 11 sockets POSIX
                                          • 111 Introduccioacuten y conceptos baacutesicos
                                          • 112 Algoritmo baacutesico Cliente-Servidor
                                          • 113 Pasos de programacioacuten C en el lado Servidor
                                          • 114 Pasos de programacioacuten C en el lado Cliente
                                            • 12 Todo junto un servidor web baacutesico en C
                                              • 121 Introduccioacuten y coacutedigo
                                              • 122 Ejercicios
                                                • 13 Ejercicio resumen 2 (1 punto)
                                                • 14 Trabajo futuro
                                                • Referencias

                      10 Sentildeales entre procesos 11

                      10 Sentildeales entre procesos

                      101 Introduccioacuten y documentacioacuten

                      Las sentildeales entre programas son interrupciones software que se generan para informara un proceso de la ocurrencia de un evento Otras formas alternativas o complementarias decomunicacioacuten entre procesos son las tuberiacuteas POSIX (funciones popen y relacionadas) y laslas colas de mensajes POSIX o POSIX message queues (funciones mq_open mq_send ) Losprogramas pueden disentildearse para capturar una o varias sentildeales proporcionando una fun-cioacuten que las maneje Este tipo de funciones se llaman teacutecnicamente callbacks o retrollamadasUna callback es una referencia a un trozo de coacutedigo ejecutable normalmente una funcioacutenque se pasa como paraacutemetro a otro coacutedigo Esto permite por ejemplo que una capa de bajonivel del software llame a la subrutina o funcioacuten 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 GNULinux se enviacutea la sentildeal SIGTERM a todos los proce-sos asiacute los procesos pueden capturar esta sentildeal y terminar de forma adecuada por ejemploliberando recursos cerrando ficheros abiertos etc La funcioacuten signal20 permite asociar unadeterminada funcioacuten (a traveacutes de un puntero a funcioacuten) a una sentildeal identificada por un en-tero (SIGTERM SIGKILL etc)

                      include ltsignalhgt

                      sighandler_t signal(int signum sighandler_t handler)

                      102 Ejercicios y ejemplos

                      El coacutedigo de ejemplo ejemplo-signalsc21 contiene ejemplos captura de sentildeales PO-SIX enviadas a un programa Recuerda que la funcioacuten signal() no llama a ninguna funcioacuten

                      19httpenwikipediaorgwikiCallback_28computer_science2920httppubsopengrouporgonlinepubs9699919799functionssignalhtml21Fuente httpwwwamparonetce155signals-exhtml

                      12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                      lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

                      $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

                      SIGKILL

                      11 sockets POSIX

                      111 Introduccioacuten y conceptos baacutesicos

                      En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

                      Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

                      socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

                      arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                      112 Algoritmo baacutesico Cliente-Servidor

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

                      Servidor

                      socket()

                      connect()

                      send()

                      recv()

                      closeSocket()

                      Cliente

                      socket()

                      bind()

                      listen()

                      accept()

                      recv()

                      send()

                      recv()

                      closeSocket()

                      El cliente enviacutea datos yel servidor los recive

                      El servidor enviacutea datos y el cliente los recive

                      El cliente manda un mensaje para finalizar la conexioacuten

                      Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                      Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                      14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                      113 Pasos de programacioacuten C en el lado Servidor

                      Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                      Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                      Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                      Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                      Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                      114 Pasos de programacioacuten C en el lado Cliente

                      Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                      Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                      Cerrar la comunicacioacuten por medio de close()

                      12 Todo junto un servidor web baacutesico en C 15

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

                      12 Todo junto un servidor web baacutesico en C

                      121 Introduccioacuten y coacutedigo

                      En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                      16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                      Servidor

                      socket()

                      connect()

                      send()

                      recv()

                      closeSocket()

                      Cliente

                      socket()

                      bind()

                      listen()

                      accept()

                      recv()

                      send()

                      recv()

                      closeSocket()

                      HTTP10 200 OKDatos

                      El cliente manda un mensaje para finalizar la conexioacuten

                      Diagrama de flujodel ejemplo de servidor web baacutesico

                      startServer()

                      while(1) fork()

                      respond()

                      fork()

                      GET holahtml HTTP11

                      La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                      El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                      Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                      122 Ejercicios

                      Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                      $ ejemplo-webserver -p 8080 -r htdocs

                      ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                      13 Ejercicio resumen 2 (1 punto) 17

                      seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                      Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                      13 Ejercicio resumen 2 (1 punto)

                      Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                      1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                      webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                      webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                      No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                      Figura 9 El Fary

                      18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                      Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                      4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                      Para el segundo ejercicio una llamada similar a

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

                      deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                      Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                      Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                      Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                      22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                      14 Trabajo futuro 19

                      Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                      20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                      Referencias

                      [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                      [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                      [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                      [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                      [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                      [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                      [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                      [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                      • 1 Introduccioacuten a POSIX
                      • 2 Objetivos
                      • 3 Entrega de praacutecticas
                      • 4 Documentacioacuten de POSIX y las bibliotecas
                      • 5 Procesado de liacutenea de comandos tipo POSIX
                        • 51 Introduccioacuten y documentacioacuten
                        • 52 Ejercicios
                          • 6 Variables de entorno
                            • 61 Introduccioacuten y documentacioacuten
                            • 62 Ejercicios
                              • 7 Obtencioacuten de informacioacuten de un usuarioa
                                • 71 Introduccioacuten y documentacioacuten
                                • 72 Ejercicios
                                  • 8 Ejercicio resumen 1 (05 punto)
                                  • 9 Creacioacuten de procesos Fork y Exec
                                    • 91 Introduccioacuten y documentacioacuten
                                    • 92 Ejercicios y ejemplos
                                      • 10 Sentildeales entre procesos
                                        • 101 Introduccioacuten y documentacioacuten
                                        • 102 Ejercicios y ejemplos
                                          • 11 sockets POSIX
                                            • 111 Introduccioacuten y conceptos baacutesicos
                                            • 112 Algoritmo baacutesico Cliente-Servidor
                                            • 113 Pasos de programacioacuten C en el lado Servidor
                                            • 114 Pasos de programacioacuten C en el lado Cliente
                                              • 12 Todo junto un servidor web baacutesico en C
                                                • 121 Introduccioacuten y coacutedigo
                                                • 122 Ejercicios
                                                  • 13 Ejercicio resumen 2 (1 punto)
                                                  • 14 Trabajo futuro
                                                  • Referencias

                        12 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                        lo que hace es asociar una funcioacuten del programador a eventos que se generan en el sistemaesto es pasar un puntero a una funcioacuten

                        $ ejemplo-signalCannot handle SIGKILLI caught the SIGHUP signalI caught the SIGTERM signalTerminado (killed) En otra terminal obtener el PID del proceso$ ps -e|grep signal31188 pts0 000005 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal mandamos sentildeal SIGTERM$ killall ejemplo-signal -9 Forzamos parar el programa con

                        SIGKILL

                        11 sockets POSIX

                        111 Introduccioacuten y conceptos baacutesicos

                        En esta seccioacuten haremos una pequentildea introduccioacuten a los sockets POSIX una herra-mienta que permite desarrollar aplicaciones que se comuniquen entre siacute a traveacutes de una redutilizando diferentes protocolos o facilitando el desarrollo de otros protocolos sobre TCPIPComo esta no es una asignatura especiacutefica de redes aprenderemos algunos conceptos y al-goritmos baacutesicos para la comunicacioacuten pero sin entrar en detalle del funcionamiento y detodas las opciones disponibles Si tienes duda sobre alguna funcioacuten hay un buen resumenen castellano con los pasos y funciones para utilizar sockets en la web chuidiangcom [7]nosotros usaremos algunas descripciones de este manual por ser muy sencillas y claras Acontinuacioacuten daremos algunas definiciones

                        Protocolo En una red de ordenadores hay varios ordenadores que estaacuten conectados entre sipor un medio fiacutesico (cable ondas inalaacutembricas etc) a traveacutes del cuaacutel puede transmitir-se informacioacuten Para que exista esta comunicacioacuten debe haber un ldquoidiomardquo o protocolocomuacuten entre los equipos Hay muchiacutesimos protocolos de comunicacioacuten entre los cua-les el maacutes extendido es el TCPIP El maacutes extendido porque es el que se utiliza enInternet

                        socket Un socket no es maacutes que un ldquocanal de comunicacioacutenrdquo entre dos programas quecorren sobre ordenadores distintos o incluso en el mismo ordenador Desde el puntode vista de programacioacuten un socket no es maacutes que un ldquoficherordquo que se abre de unamanera especial Una vez abierto se pueden escribir y leer datos de eacutel con las habitualesfunciones de read() y write() del lenguaje C Existen baacutesicamente dos tipos deldquocanales de comunicacioacutenrdquo o sockets los orientados a conexioacuten (por ejemplo TCP)y los no orientados a conexioacuten (por ejemplo UDP) Nosotros veremos un ejemplo defuncionamiento de sockets orientados a la conexioacuten

                        arquitectura cliente-servidor La arquitectura cliente-servidor es un modelo de aplicacioacutendistribuida 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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                        112 Algoritmo baacutesico Cliente-Servidor

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

                        Servidor

                        socket()

                        connect()

                        send()

                        recv()

                        closeSocket()

                        Cliente

                        socket()

                        bind()

                        listen()

                        accept()

                        recv()

                        send()

                        recv()

                        closeSocket()

                        El cliente enviacutea datos yel servidor los recive

                        El servidor enviacutea datos y el cliente los recive

                        El cliente manda un mensaje para finalizar la conexioacuten

                        Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                        Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                        14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                        113 Pasos de programacioacuten C en el lado Servidor

                        Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                        Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                        Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                        Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                        Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                        114 Pasos de programacioacuten C en el lado Cliente

                        Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                        Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                        Cerrar la comunicacioacuten por medio de close()

                        12 Todo junto un servidor web baacutesico en C 15

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

                        12 Todo junto un servidor web baacutesico en C

                        121 Introduccioacuten y coacutedigo

                        En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                        16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                        Servidor

                        socket()

                        connect()

                        send()

                        recv()

                        closeSocket()

                        Cliente

                        socket()

                        bind()

                        listen()

                        accept()

                        recv()

                        send()

                        recv()

                        closeSocket()

                        HTTP10 200 OKDatos

                        El cliente manda un mensaje para finalizar la conexioacuten

                        Diagrama de flujodel ejemplo de servidor web baacutesico

                        startServer()

                        while(1) fork()

                        respond()

                        fork()

                        GET holahtml HTTP11

                        La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                        El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                        Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                        122 Ejercicios

                        Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                        $ ejemplo-webserver -p 8080 -r htdocs

                        ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                        13 Ejercicio resumen 2 (1 punto) 17

                        seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                        Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                        13 Ejercicio resumen 2 (1 punto)

                        Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                        1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                        webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                        webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                        No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                        Figura 9 El Fary

                        18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                        Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                        4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                        Para el segundo ejercicio una llamada similar a

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

                        deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                        Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                        Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                        Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                        22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                        14 Trabajo futuro 19

                        Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                        20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                        Referencias

                        [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                        [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                        [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                        [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                        [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                        [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                        [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                        [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                        • 1 Introduccioacuten a POSIX
                        • 2 Objetivos
                        • 3 Entrega de praacutecticas
                        • 4 Documentacioacuten de POSIX y las bibliotecas
                        • 5 Procesado de liacutenea de comandos tipo POSIX
                          • 51 Introduccioacuten y documentacioacuten
                          • 52 Ejercicios
                            • 6 Variables de entorno
                              • 61 Introduccioacuten y documentacioacuten
                              • 62 Ejercicios
                                • 7 Obtencioacuten de informacioacuten de un usuarioa
                                  • 71 Introduccioacuten y documentacioacuten
                                  • 72 Ejercicios
                                    • 8 Ejercicio resumen 1 (05 punto)
                                    • 9 Creacioacuten de procesos Fork y Exec
                                      • 91 Introduccioacuten y documentacioacuten
                                      • 92 Ejercicios y ejemplos
                                        • 10 Sentildeales entre procesos
                                          • 101 Introduccioacuten y documentacioacuten
                                          • 102 Ejercicios y ejemplos
                                            • 11 sockets POSIX
                                              • 111 Introduccioacuten y conceptos baacutesicos
                                              • 112 Algoritmo baacutesico Cliente-Servidor
                                              • 113 Pasos de programacioacuten C en el lado Servidor
                                              • 114 Pasos de programacioacuten C en el lado Cliente
                                                • 12 Todo junto un servidor web baacutesico en C
                                                  • 121 Introduccioacuten y coacutedigo
                                                  • 122 Ejercicios
                                                    • 13 Ejercicio resumen 2 (1 punto)
                                                    • 14 Trabajo futuro
                                                    • Referencias

                          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 conexioacuten con eacutel normalmente para pedirlealguacuten dato Cliente es el programa que solicita la conexioacuten para normalmente pedirdatos al servidor

                          112 Algoritmo baacutesico Cliente-Servidor

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

                          Servidor

                          socket()

                          connect()

                          send()

                          recv()

                          closeSocket()

                          Cliente

                          socket()

                          bind()

                          listen()

                          accept()

                          recv()

                          send()

                          recv()

                          closeSocket()

                          El cliente enviacutea datos yel servidor los recive

                          El servidor enviacutea datos y el cliente los recive

                          El cliente manda un mensaje para finalizar la conexioacuten

                          Diagrama de flujode un socket TCPimplementando el modeloCliente-Servidor

                          Figura 6 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                          14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                          113 Pasos de programacioacuten C en el lado Servidor

                          Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                          Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                          Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                          Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                          Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                          114 Pasos de programacioacuten C en el lado Cliente

                          Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                          Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                          Cerrar la comunicacioacuten por medio de close()

                          12 Todo junto un servidor web baacutesico en C 15

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

                          12 Todo junto un servidor web baacutesico en C

                          121 Introduccioacuten y coacutedigo

                          En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                          16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                          Servidor

                          socket()

                          connect()

                          send()

                          recv()

                          closeSocket()

                          Cliente

                          socket()

                          bind()

                          listen()

                          accept()

                          recv()

                          send()

                          recv()

                          closeSocket()

                          HTTP10 200 OKDatos

                          El cliente manda un mensaje para finalizar la conexioacuten

                          Diagrama de flujodel ejemplo de servidor web baacutesico

                          startServer()

                          while(1) fork()

                          respond()

                          fork()

                          GET holahtml HTTP11

                          La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                          El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                          Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                          122 Ejercicios

                          Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                          $ ejemplo-webserver -p 8080 -r htdocs

                          ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                          13 Ejercicio resumen 2 (1 punto) 17

                          seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                          Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                          13 Ejercicio resumen 2 (1 punto)

                          Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                          1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                          webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                          webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                          No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                          Figura 9 El Fary

                          18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                          Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                          4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                          Para el segundo ejercicio una llamada similar a

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

                          deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                          Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                          Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                          Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                          22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                          14 Trabajo futuro 19

                          Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                          20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                          Referencias

                          [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                          [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                          [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                          [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                          [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                          [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                          [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                          [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                          • 1 Introduccioacuten a POSIX
                          • 2 Objetivos
                          • 3 Entrega de praacutecticas
                          • 4 Documentacioacuten de POSIX y las bibliotecas
                          • 5 Procesado de liacutenea de comandos tipo POSIX
                            • 51 Introduccioacuten y documentacioacuten
                            • 52 Ejercicios
                              • 6 Variables de entorno
                                • 61 Introduccioacuten y documentacioacuten
                                • 62 Ejercicios
                                  • 7 Obtencioacuten de informacioacuten de un usuarioa
                                    • 71 Introduccioacuten y documentacioacuten
                                    • 72 Ejercicios
                                      • 8 Ejercicio resumen 1 (05 punto)
                                      • 9 Creacioacuten de procesos Fork y Exec
                                        • 91 Introduccioacuten y documentacioacuten
                                        • 92 Ejercicios y ejemplos
                                          • 10 Sentildeales entre procesos
                                            • 101 Introduccioacuten y documentacioacuten
                                            • 102 Ejercicios y ejemplos
                                              • 11 sockets POSIX
                                                • 111 Introduccioacuten y conceptos baacutesicos
                                                • 112 Algoritmo baacutesico Cliente-Servidor
                                                • 113 Pasos de programacioacuten C en el lado Servidor
                                                • 114 Pasos de programacioacuten C en el lado Cliente
                                                  • 12 Todo junto un servidor web baacutesico en C
                                                    • 121 Introduccioacuten y coacutedigo
                                                    • 122 Ejercicios
                                                      • 13 Ejercicio resumen 2 (1 punto)
                                                      • 14 Trabajo futuro
                                                      • Referencias

                            14 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                            113 Pasos de programacioacuten C en el lado Servidor

                            Con C en UnixLinux los pasos que debe seguir un programa servidor son los siguientes[7]

                            Apertura de un socket mediante la funcioacuten socket() Esta funcioacuten devuelve un des-criptor de fichero normal como puede devolverlo open() o fopen() La funcioacutensocket() no hace absolutamente nada respecto a iniciar la comunicacioacuten salvo de-volvernos y preparar un descriptor de fichero que el sistema posteriormente asociaraacutea una conexioacuten en red

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

                            Avisar al sistema de que comience a atender dicha conexioacuten de red Se consigue me-diante la funcioacuten listen() A partir de este momento el sistema operativo anotaraacutela conexioacuten de cualquier cliente para pasaacuternosla cuando se lo pidamos Si llegan clien-tes maacutes raacutepido de lo que somos capaces de atenderlos el sistema operativo hace unaldquocolardquo con ellos y nos los iraacute pasando seguacuten vayamos pidieacutendolo

                            Pedir y aceptar las conexiones de clientes al sistema operativo Para ello hacemos unallamada a la funcioacuten accept() Esta funcioacuten le indica al sistema operativo que nos deacuteal siguiente cliente de la cola Si no hay clientes se quedaraacute bloqueada hasta que alguacutencliente 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 Obviamentetanto cliente como servidor deben saber queacute datos esperan recibir queacute datos debenenviar y en queacute formato por ejemplo el protocolo HTTP y el formato HTML o XHTML

                            Cierre de la comunicacioacuten y del socket por medio de la funcioacuten close() que es lamisma que sirve para cerrar un fichero

                            114 Pasos de programacioacuten C en el lado Cliente

                            Nosotros no veremos la parte del cliente ya que cualquier navegador web seraacute 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 funcioacuten socket()

                            Solicitar conexioacuten con el servidor por medio de la funcioacuten connect() Dicha funcioacutenquedaraacute bloqueada hasta que el servidor acepte nuestra conexioacuten o bien si no hayservidor en el sitio indicado saldraacute dando un error En esta llamada se debe facilitar ladireccioacuten IP del servidor y el nuacutemero de servicio que se desea

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

                            Cerrar la comunicacioacuten por medio de close()

                            12 Todo junto un servidor web baacutesico en C 15

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

                            12 Todo junto un servidor web baacutesico en C

                            121 Introduccioacuten y coacutedigo

                            En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                            16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                            Servidor

                            socket()

                            connect()

                            send()

                            recv()

                            closeSocket()

                            Cliente

                            socket()

                            bind()

                            listen()

                            accept()

                            recv()

                            send()

                            recv()

                            closeSocket()

                            HTTP10 200 OKDatos

                            El cliente manda un mensaje para finalizar la conexioacuten

                            Diagrama de flujodel ejemplo de servidor web baacutesico

                            startServer()

                            while(1) fork()

                            respond()

                            fork()

                            GET holahtml HTTP11

                            La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                            El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                            Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                            122 Ejercicios

                            Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                            $ ejemplo-webserver -p 8080 -r htdocs

                            ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                            13 Ejercicio resumen 2 (1 punto) 17

                            seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                            Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                            13 Ejercicio resumen 2 (1 punto)

                            Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                            1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                            webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                            webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                            No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                            Figura 9 El Fary

                            18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                            Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                            4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                            Para el segundo ejercicio una llamada similar a

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

                            deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                            Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                            Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                            Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                            22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                            14 Trabajo futuro 19

                            Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                            20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                            Referencias

                            [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                            [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                            [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                            [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                            [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                            [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                            [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                            [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                            • 1 Introduccioacuten a POSIX
                            • 2 Objetivos
                            • 3 Entrega de praacutecticas
                            • 4 Documentacioacuten de POSIX y las bibliotecas
                            • 5 Procesado de liacutenea de comandos tipo POSIX
                              • 51 Introduccioacuten y documentacioacuten
                              • 52 Ejercicios
                                • 6 Variables de entorno
                                  • 61 Introduccioacuten y documentacioacuten
                                  • 62 Ejercicios
                                    • 7 Obtencioacuten de informacioacuten de un usuarioa
                                      • 71 Introduccioacuten y documentacioacuten
                                      • 72 Ejercicios
                                        • 8 Ejercicio resumen 1 (05 punto)
                                        • 9 Creacioacuten de procesos Fork y Exec
                                          • 91 Introduccioacuten y documentacioacuten
                                          • 92 Ejercicios y ejemplos
                                            • 10 Sentildeales entre procesos
                                              • 101 Introduccioacuten y documentacioacuten
                                              • 102 Ejercicios y ejemplos
                                                • 11 sockets POSIX
                                                  • 111 Introduccioacuten y conceptos baacutesicos
                                                  • 112 Algoritmo baacutesico Cliente-Servidor
                                                  • 113 Pasos de programacioacuten C en el lado Servidor
                                                  • 114 Pasos de programacioacuten C en el lado Cliente
                                                    • 12 Todo junto un servidor web baacutesico en C
                                                      • 121 Introduccioacuten y coacutedigo
                                                      • 122 Ejercicios
                                                        • 13 Ejercicio resumen 2 (1 punto)
                                                        • 14 Trabajo futuro
                                                        • Referencias

                              12 Todo junto un servidor web baacutesico en C 15

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

                              12 Todo junto un servidor web baacutesico en C

                              121 Introduccioacuten y coacutedigo

                              En esta seccioacuten vamos a ver un ejemplo que combina muchas de las funciones POSIXque hemos visto en las praacutecticas Esta seccioacuten la trabajaremos directamente sobre el coacutedigode ejemplo ejemplo-webserverc Este ejemplo es un coacutedigo ampliado descargado deinternet con algunas funciones auxiliares que se han antildeadido para facilitar los ejerciciosPregunta todas las dudas que tengas durante la explicacioacuten del coacutedigo 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 pediraacute ninguna modificacioacuten de las partes de coacutedigorelativas a la comunicacioacuten La Figura 8 muestra el funcionamiento general del coacutedigo delservidor web combinando el esquema de la Figura 6 con fork() para poder atender variasconexiones de manera simultaacutenea

                              16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                              Servidor

                              socket()

                              connect()

                              send()

                              recv()

                              closeSocket()

                              Cliente

                              socket()

                              bind()

                              listen()

                              accept()

                              recv()

                              send()

                              recv()

                              closeSocket()

                              HTTP10 200 OKDatos

                              El cliente manda un mensaje para finalizar la conexioacuten

                              Diagrama de flujodel ejemplo de servidor web baacutesico

                              startServer()

                              while(1) fork()

                              respond()

                              fork()

                              GET holahtml HTTP11

                              La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                              El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                              Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                              122 Ejercicios

                              Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                              $ ejemplo-webserver -p 8080 -r htdocs

                              ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                              13 Ejercicio resumen 2 (1 punto) 17

                              seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                              Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                              13 Ejercicio resumen 2 (1 punto)

                              Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                              1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                              webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                              webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                              No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                              Figura 9 El Fary

                              18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                              Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                              4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                              Para el segundo ejercicio una llamada similar a

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

                              deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                              Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                              Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                              Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                              22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                              14 Trabajo futuro 19

                              Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                              20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                              Referencias

                              [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                              [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                              [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                              [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                              [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                              [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                              [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                              [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                              • 1 Introduccioacuten a POSIX
                              • 2 Objetivos
                              • 3 Entrega de praacutecticas
                              • 4 Documentacioacuten de POSIX y las bibliotecas
                              • 5 Procesado de liacutenea de comandos tipo POSIX
                                • 51 Introduccioacuten y documentacioacuten
                                • 52 Ejercicios
                                  • 6 Variables de entorno
                                    • 61 Introduccioacuten y documentacioacuten
                                    • 62 Ejercicios
                                      • 7 Obtencioacuten de informacioacuten de un usuarioa
                                        • 71 Introduccioacuten y documentacioacuten
                                        • 72 Ejercicios
                                          • 8 Ejercicio resumen 1 (05 punto)
                                          • 9 Creacioacuten de procesos Fork y Exec
                                            • 91 Introduccioacuten y documentacioacuten
                                            • 92 Ejercicios y ejemplos
                                              • 10 Sentildeales entre procesos
                                                • 101 Introduccioacuten y documentacioacuten
                                                • 102 Ejercicios y ejemplos
                                                  • 11 sockets POSIX
                                                    • 111 Introduccioacuten y conceptos baacutesicos
                                                    • 112 Algoritmo baacutesico Cliente-Servidor
                                                    • 113 Pasos de programacioacuten C en el lado Servidor
                                                    • 114 Pasos de programacioacuten C en el lado Cliente
                                                      • 12 Todo junto un servidor web baacutesico en C
                                                        • 121 Introduccioacuten y coacutedigo
                                                        • 122 Ejercicios
                                                          • 13 Ejercicio resumen 2 (1 punto)
                                                          • 14 Trabajo futuro
                                                          • Referencias

                                16 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                Servidor

                                socket()

                                connect()

                                send()

                                recv()

                                closeSocket()

                                Cliente

                                socket()

                                bind()

                                listen()

                                accept()

                                recv()

                                send()

                                recv()

                                closeSocket()

                                HTTP10 200 OKDatos

                                El cliente manda un mensaje para finalizar la conexioacuten

                                Diagrama de flujodel ejemplo de servidor web baacutesico

                                startServer()

                                while(1) fork()

                                respond()

                                fork()

                                GET holahtml HTTP11

                                La llamada a accept() crea un nuevosocket para atender la conexioacutenque deberaacute ser cerrado al finalizarel intercambio de datos

                                El socket creado por el procesoprincipal deberiacutea ser cerradoal finalizar el programa por ejemplo capturando lassentildeales SIGTERM SIGINT

                                Figura 8 Diagrama de flujo de la implementacioacuten del modelo Cliente-Servidor orientado ala conexioacuten con sockets POSIX

                                122 Ejercicios

                                Arranca y para el servidor siguiendo la ayuda de la liacutenea de comandos Prueba a conec-tarte a eacutel a traveacutes del navegador y prueba a cambiar las opciones Si no sabes HTML miralos ficheros de ejemplo del directorio htdocs del paquete de praacutecticas

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

                                $ ejemplo-webserver -p 8080 -r htdocs

                                ahora visita la direccioacuten httplocalhost8080 y comprueba que puedes navegar porlas paacuteginas alojadas en el servidor En el navegador deberiacuteas obtener un resultado similar alde la Figura 7 Puedes probar a ejecutar el servidor en tsucoes en este caso la direccioacuten

                                13 Ejercicio resumen 2 (1 punto) 17

                                seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                                Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                                13 Ejercicio resumen 2 (1 punto)

                                Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                                1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                                webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                                webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                                No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                                Figura 9 El Fary

                                18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                                4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                                Para el segundo ejercicio una llamada similar a

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

                                deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                                Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                                Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                                Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                                22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                                14 Trabajo futuro 19

                                Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                                20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                Referencias

                                [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                                [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                                [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                                [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                                [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                                [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                                [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                                [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                                • 1 Introduccioacuten a POSIX
                                • 2 Objetivos
                                • 3 Entrega de praacutecticas
                                • 4 Documentacioacuten de POSIX y las bibliotecas
                                • 5 Procesado de liacutenea de comandos tipo POSIX
                                  • 51 Introduccioacuten y documentacioacuten
                                  • 52 Ejercicios
                                    • 6 Variables de entorno
                                      • 61 Introduccioacuten y documentacioacuten
                                      • 62 Ejercicios
                                        • 7 Obtencioacuten de informacioacuten de un usuarioa
                                          • 71 Introduccioacuten y documentacioacuten
                                          • 72 Ejercicios
                                            • 8 Ejercicio resumen 1 (05 punto)
                                            • 9 Creacioacuten de procesos Fork y Exec
                                              • 91 Introduccioacuten y documentacioacuten
                                              • 92 Ejercicios y ejemplos
                                                • 10 Sentildeales entre procesos
                                                  • 101 Introduccioacuten y documentacioacuten
                                                  • 102 Ejercicios y ejemplos
                                                    • 11 sockets POSIX
                                                      • 111 Introduccioacuten y conceptos baacutesicos
                                                      • 112 Algoritmo baacutesico Cliente-Servidor
                                                      • 113 Pasos de programacioacuten C en el lado Servidor
                                                      • 114 Pasos de programacioacuten C en el lado Cliente
                                                        • 12 Todo junto un servidor web baacutesico en C
                                                          • 121 Introduccioacuten y coacutedigo
                                                          • 122 Ejercicios
                                                            • 13 Ejercicio resumen 2 (1 punto)
                                                            • 14 Trabajo futuro
                                                            • Referencias

                                  13 Ejercicio resumen 2 (1 punto) 17

                                  seriacutea httptsucoes8080 Si esto lo haceacuteis varias personas tal vez tengaacuteis quecambiar el puerto porque soacutelo una aplicacioacuten puede escuchar en un puerto este mensajede error os indicariacutea que ya hay una aplicacioacuten asociada al puerto que pretendeacuteis usar

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

                                  Este mensaje de error puede obtenerse auacuten cuando haya finalizado la ejecucioacuten de pro-grama que escucha el puerto Aunque el documento es antiguo y la explicacioacuten tal vez nosea precisa puedes leer una explicacioacuten de por queacute pasa esto en [8]

                                  13 Ejercicio resumen 2 (1 punto)

                                  Para este ejercicio partiremos del coacutedigo ejemplo-webserverc El Makefile del pa-quete de praacutecticas ya incluye una regla para compilar el fichero webserverexc Ejercicios

                                  1 La funcioacuten webServerLog() implementa un pequentildeo sistema de registro o log (nooacuteptimo por supuesto) Esta funcioacuten es similar a printf() Utilizaacutendola se puedenregistrar mensajes de inicio o parada del servidor o los accesos al servidor en el ficheroaccesslog y los errores en el fichero errorlog Por ejemplo puedes hacer lassiguientes llamadas

                                  webServerLog(WS_LOG_ACCESS Servidor iniciado en el puerto s PORT)

                                  webServerLog(WS_LOG_ERROR Error en la conexioacuten)

                                  No necesitas reemplazar todos los mensajes pero si los maacutes 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 coacutedigo del servidor web para que tenga una nueva opcioacuten -f Cuando sepase esta opcioacuten el servidor deberaacute incluir una foto del Fary en todas las paacuteginas webque sirva Una imagen se incluye en HTML con el coacutedigoltimg src=ficherojpg alt=Texto alternativogt insertado entre las eti-quetas ltBODYgt y ltBODYgt que es donde va el contenido en si de una paacutegina HTML

                                  Figura 9 El Fary

                                  18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                  Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                                  4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                                  Para el segundo ejercicio una llamada similar a

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

                                  deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                                  Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                                  Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                                  Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                                  22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                                  14 Trabajo futuro 19

                                  Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                                  20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                  Referencias

                                  [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                                  [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                                  [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                                  [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                                  [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                                  [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                                  [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                                  [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                                  • 1 Introduccioacuten a POSIX
                                  • 2 Objetivos
                                  • 3 Entrega de praacutecticas
                                  • 4 Documentacioacuten de POSIX y las bibliotecas
                                  • 5 Procesado de liacutenea de comandos tipo POSIX
                                    • 51 Introduccioacuten y documentacioacuten
                                    • 52 Ejercicios
                                      • 6 Variables de entorno
                                        • 61 Introduccioacuten y documentacioacuten
                                        • 62 Ejercicios
                                          • 7 Obtencioacuten de informacioacuten de un usuarioa
                                            • 71 Introduccioacuten y documentacioacuten
                                            • 72 Ejercicios
                                              • 8 Ejercicio resumen 1 (05 punto)
                                              • 9 Creacioacuten de procesos Fork y Exec
                                                • 91 Introduccioacuten y documentacioacuten
                                                • 92 Ejercicios y ejemplos
                                                  • 10 Sentildeales entre procesos
                                                    • 101 Introduccioacuten y documentacioacuten
                                                    • 102 Ejercicios y ejemplos
                                                      • 11 sockets POSIX
                                                        • 111 Introduccioacuten y conceptos baacutesicos
                                                        • 112 Algoritmo baacutesico Cliente-Servidor
                                                        • 113 Pasos de programacioacuten C en el lado Servidor
                                                        • 114 Pasos de programacioacuten C en el lado Cliente
                                                          • 12 Todo junto un servidor web baacutesico en C
                                                            • 121 Introduccioacuten y coacutedigo
                                                            • 122 Ejercicios
                                                              • 13 Ejercicio resumen 2 (1 punto)
                                                              • 14 Trabajo futuro
                                                              • Referencias

                                    18 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                    Ten en cuenta que el navegador haraacute una peticioacuten por cada fichero html y otra(s) porcada imagen (u otros datos) contenidos en la web Asiacute si una web tiene una imagenel navegador pediraacute primero el fichero html con un GET holahtml HTTP11 ycuando lo abra y detecte la etiqueta ltimg gt haraacute otra peticioacuten GET ficherojpgHTTP11 para que el servidor le enviacutee el fichero de la imagen22 Ayuacutedate y modificasi lo necesitas las funciones auxiliares strcasestr()23 y copyfile() Acueacuterdate 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 sentildeales con la misma fun-cioacuten de parar el servidor Se deberiacutean finalizar y cerrar adecuadamente las conexionesy ficheros abiertos Opcionalmente puedes hacer un script de bash que arranque y pareel servidor ejecutando el servidor y enviaacutendole la sentildeal SIGTERM respectivamente Porejemplo start-serversh y stop-serversh

                                    4 Captura la URL solicitada por el cliente Si se pide la URL httpservidorpuertoinfousuarioi02samoj el servidor debe generar una web con la informacioacuten delusuario Con el coacutedigo del ejercicio resumen 1 y usando un fichero temporal no debe-riacutea ser muy difiacutecil

                                    Para el segundo ejercicio una llamada similar a

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

                                    deberiacutea 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 patroacuten de disentildeo singleton para guardar la configuracioacuten del programa

                                    Controlar la destruccioacuten de subprocesos del servidor pasado un tiempo

                                    Comunicacioacuten inter-procesos con diferentes alternativas (tuberiacuteas POSIX MQ etc)

                                    Capturar coacutemo ha muerto un proceso WEXITSTATUS WTERMSIG

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

                                    22La peticioacuten de estos ficheros auxiliares se hace al servidor que sirve la web pero tambieacuten se puede hacer aotro si el fichero se encuentra en otro sitio web Esto ocurre por ejemplo cuando se inserta un viacutedeo de youtube osimilares en una paacutegina

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

                                    14 Trabajo futuro 19

                                    Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                                    20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                    Referencias

                                    [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                                    [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                                    [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                                    [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                                    [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                                    [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                                    [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                                    [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                                    • 1 Introduccioacuten a POSIX
                                    • 2 Objetivos
                                    • 3 Entrega de praacutecticas
                                    • 4 Documentacioacuten de POSIX y las bibliotecas
                                    • 5 Procesado de liacutenea de comandos tipo POSIX
                                      • 51 Introduccioacuten y documentacioacuten
                                      • 52 Ejercicios
                                        • 6 Variables de entorno
                                          • 61 Introduccioacuten y documentacioacuten
                                          • 62 Ejercicios
                                            • 7 Obtencioacuten de informacioacuten de un usuarioa
                                              • 71 Introduccioacuten y documentacioacuten
                                              • 72 Ejercicios
                                                • 8 Ejercicio resumen 1 (05 punto)
                                                • 9 Creacioacuten de procesos Fork y Exec
                                                  • 91 Introduccioacuten y documentacioacuten
                                                  • 92 Ejercicios y ejemplos
                                                    • 10 Sentildeales entre procesos
                                                      • 101 Introduccioacuten y documentacioacuten
                                                      • 102 Ejercicios y ejemplos
                                                        • 11 sockets POSIX
                                                          • 111 Introduccioacuten y conceptos baacutesicos
                                                          • 112 Algoritmo baacutesico Cliente-Servidor
                                                          • 113 Pasos de programacioacuten C en el lado Servidor
                                                          • 114 Pasos de programacioacuten C en el lado Cliente
                                                            • 12 Todo junto un servidor web baacutesico en C
                                                              • 121 Introduccioacuten y coacutedigo
                                                              • 122 Ejercicios
                                                                • 13 Ejercicio resumen 2 (1 punto)
                                                                • 14 Trabajo futuro
                                                                • Referencias

                                      14 Trabajo futuro 19

                                      Figura 10 Ejemplo del resultado de la ejecucioacuten del servidor web para implementar la op-cioacuten -f

                                      20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                      Referencias

                                      [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                                      [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                                      [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                                      [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                                      [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                                      [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                                      [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                                      [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                                      • 1 Introduccioacuten a POSIX
                                      • 2 Objetivos
                                      • 3 Entrega de praacutecticas
                                      • 4 Documentacioacuten de POSIX y las bibliotecas
                                      • 5 Procesado de liacutenea de comandos tipo POSIX
                                        • 51 Introduccioacuten y documentacioacuten
                                        • 52 Ejercicios
                                          • 6 Variables de entorno
                                            • 61 Introduccioacuten y documentacioacuten
                                            • 62 Ejercicios
                                              • 7 Obtencioacuten de informacioacuten de un usuarioa
                                                • 71 Introduccioacuten y documentacioacuten
                                                • 72 Ejercicios
                                                  • 8 Ejercicio resumen 1 (05 punto)
                                                  • 9 Creacioacuten de procesos Fork y Exec
                                                    • 91 Introduccioacuten y documentacioacuten
                                                    • 92 Ejercicios y ejemplos
                                                      • 10 Sentildeales entre procesos
                                                        • 101 Introduccioacuten y documentacioacuten
                                                        • 102 Ejercicios y ejemplos
                                                          • 11 sockets POSIX
                                                            • 111 Introduccioacuten y conceptos baacutesicos
                                                            • 112 Algoritmo baacutesico Cliente-Servidor
                                                            • 113 Pasos de programacioacuten C en el lado Servidor
                                                            • 114 Pasos de programacioacuten C en el lado Cliente
                                                              • 12 Todo junto un servidor web baacutesico en C
                                                                • 121 Introduccioacuten y coacutedigo
                                                                • 122 Ejercicios
                                                                  • 13 Ejercicio resumen 2 (1 punto)
                                                                  • 14 Trabajo futuro
                                                                  • Referencias

                                        20 Programacioacuten y Administracioacuten de Sistemasndash 2011-2012

                                        Referencias

                                        [1] Wikipedia Posix ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=POSIXampoldid=53746603

                                        [2] The IEEE and The Open Group Posix1-2008 ndash the open group base specifications issue 72008 Available from httppubsopengrouporgonlinepubs9699919799

                                        [3] Proyecto GNU Gnu c library 2012 Available from httpwwwgnuorgsoftwarelibclibchtml

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

                                        [5] Wikipedia Glibc ndash wikipedia la enciclopedia libre 2012 [Internet descargado 12-abril-2012] Available from httpeswikipediaorgwindexphptitle=Glibcampoldid=53229698

                                        [6] Tim Love Fork and exec 2008 Available from httpwww-hengcamacukhelptplunixforkhtml

                                        [7] chuidiangcom Programacioacuten de sockets en c de unixlinux 2007 Available fromhttpwwwchuidiangcomclinuxsocketssockets_simpphp

                                        [8] Andrew Gierth Vic Metcalfe and other contributers Programming UNIX Sockets inC - Frequently Asked Questions 42 Why donrsquot my sockets close 1996 Availa-ble from httpwwwsoftlabntuagrfacilitiesdocumentationunixunix-socket-faqunix-socket-faq-4htmlss42

                                        [9] Wikipedia Dennis ritchie ndash wikipedia la enciclopedia libre 2012 Available from httpeswikipediaorgwikiDennis_Ritchie

                                        • 1 Introduccioacuten a POSIX
                                        • 2 Objetivos
                                        • 3 Entrega de praacutecticas
                                        • 4 Documentacioacuten de POSIX y las bibliotecas
                                        • 5 Procesado de liacutenea de comandos tipo POSIX
                                          • 51 Introduccioacuten y documentacioacuten
                                          • 52 Ejercicios
                                            • 6 Variables de entorno
                                              • 61 Introduccioacuten y documentacioacuten
                                              • 62 Ejercicios
                                                • 7 Obtencioacuten de informacioacuten de un usuarioa
                                                  • 71 Introduccioacuten y documentacioacuten
                                                  • 72 Ejercicios
                                                    • 8 Ejercicio resumen 1 (05 punto)
                                                    • 9 Creacioacuten de procesos Fork y Exec
                                                      • 91 Introduccioacuten y documentacioacuten
                                                      • 92 Ejercicios y ejemplos
                                                        • 10 Sentildeales entre procesos
                                                          • 101 Introduccioacuten y documentacioacuten
                                                          • 102 Ejercicios y ejemplos
                                                            • 11 sockets POSIX
                                                              • 111 Introduccioacuten y conceptos baacutesicos
                                                              • 112 Algoritmo baacutesico Cliente-Servidor
                                                              • 113 Pasos de programacioacuten C en el lado Servidor
                                                              • 114 Pasos de programacioacuten C en el lado Cliente
                                                                • 12 Todo junto un servidor web baacutesico en C
                                                                  • 121 Introduccioacuten y coacutedigo
                                                                  • 122 Ejercicios
                                                                    • 13 Ejercicio resumen 2 (1 punto)
                                                                    • 14 Trabajo futuro
                                                                    • Referencias

                                          top related