-
Prctica3: Programacin POSIXProgramacin y Administracin de
Sistemas
2011-2012
Javier Snchez [email protected]
2o curso de Grado en Ingeniera InformticaDepartamento de
Informtica y Anlisis Numrico
Escuela Politcnica SuperiorUniversidad de Crdoba
26 de octubre de 2012
ResumenEntre otras cosas, el estndar POSIX define una serie de
funciones (comportamiento,
parmetros y valores devueltos) que deben proporcionar todos los
sistemas operativosque quieran satisfacer el estndar. De esta
forma, si una aplicacin hace un buen uso deestas funciones deber
compilar y ejecutarse sin problemas en cualquier sistema
operativoPOSIX. En esta prctica vamos a conocer qu es el estndar
POSIX, y una implementa-cin de la biblioteca C de POSIX, la
biblioteca libre GNU C Library o glibc. En Moodle seadjunta el
fichero pas-practica3.tgz que contiene cdigo de ejemplo de las
funcio-nes que iremos viendo en clase.
ndice
1. Introduccin a POSIX 2
2. Objetivos 4
3. Entrega de prcticas 4
4. Documentacin de POSIX y las bibliotecas 4
5. Procesado de lnea de comandos tipo POSIX 45.1. Introduccin y
documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . .
45.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . 5
6. Variables de entorno 56.1. Introduccin y documentacin . . . .
. . . . . . . . . . . . . . . . . . . . . . . 56.2. Ejercicios . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . 6
1
[email protected]
-
2 Programacin y Administracin de Sistemas 2011-2012
7. Obtencin de informacin de un usuario/a 67.1. Introduccin y
documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . .
67.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . 6
8. Ejercicio resumen 1 (0.5 punto) 7
9. Creacin de procesos Fork y Exec 79.1. Introduccin y
documentacin . . . . . . . . . . . . . . . . . . . . . . . . . . .
79.2. Ejercicios y ejemplos . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . 8
10. Seales entre procesos 1110.1. Introduccin y documentacin . .
. . . . . . . . . . . . . . . . . . . . . . . . . 1110.2.
Ejercicios y ejemplos . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . 11
11. sockets POSIX 1211.1. Introduccin y conceptos bsicos . . . .
. . . . . . . . . . . . . . . . . . . . . . 1211.2. Algoritmo bsico
Cliente-Servidor . . . . . . . . . . . . . . . . . . . . . . . . .
1311.3. Pasos de programacin C en el lado Servidor . . . . . . . .
. . . . . . . . . . . 1411.4. Pasos de programacin C en el lado
Cliente . . . . . . . . . . . . . . . . . . . . 14
12. Todo junto: un servidor web bsico en C 1512.1. Introduccin y
cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. 1512.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . 16
13. Ejercicio resumen 2 (1 punto) 17
14. Trabajo futuro 18
Referencias 18
1. Introduccin a POSIX
Figura 1: Mascota delproyecto GNU (http://www.gnu.org/)
POSIX es el acrnimo de Portable Operating System Interface; la
Xviene de UNIX como sea de identidad de la API (Application
Pro-gramming Interface, interfaz de programacin de aplicaciones).
Son unafamilia de estndares de llamadas al sistema operativo
definidospor el IEEE (Institute of Electrical and Electronics
Engineers, Institutode Ingenieros Elctricos y Electrnicos) y
especificados formalmenteen el IEEE 1003. Persiguen generalizar las
interfaces de los sistemasoperativos para que una misma aplicacin
pueda ejecutarse en dis-tintas plataformas. Estos estndares
surgieron de un proyecto denormalizacin de las API y describen un
conjunto de interfaces deaplicacin adaptables a una gran variedad
de implementaciones desistemas operativos [1]. La ltima versin de
la especificacin POSIX es del ao 2008, se cono-ce por POSIX.1-2008,
IEEE Std 1003.1-2008 y por The Open Group Technical StandardBase
Specifications, Issue 7[2].
http://www.gnu.org/http://www.gnu.org/
-
1. Introduccin a POSIX 3
Figura 2: Dennis MacAlistair Ritchie. Colabor en el diseo y
desarrollo de los sistemasoperativos Multics y Unix, as como el
desarrollo de varios lenguajes de programacin comoel C, tema sobre
el cual escribi un clebre clsico de las ciencias de la computacin
junto aBrian Wilson Kernighan: El lenguaje de programacin C
[4].
GNU C Library, comnmente conocida como glibc es la biblioteca
estndar de lenguajeC de GNU. Se distribuye bajo los trminos de la
licencia GNU LGPL. Esta biblioteca siguetodos los estndares ms
relevantes como ISO C99 y POSIX.1-2008 [3]. gnulib, tambinconocida
como Biblioteca de portabilidad de GNU es una coleccin de
subrutinas disea-das para usarse en distintos sistemas operativos y
arquitecturas. El objetivo de esta segundabiblioteca es facilitar
el desarrollo multi-plataforma de aplicaciones de software
libre.
Figura 3: GNU + Linux = GNU/Linux
En los sistemas en los que se usan, estasbibliotecas de C
proporcionan y definen lasllamadas al sistema y otras funciones
bsi-cas, y son utilizadas por casi todos los pro-gramas. Sobre
todo, es muy usada en los sis-temas GNU y en el kernel de Linux.
Cuan-do hablamos de Linux como sistema opera-tivo completo debemos
referirnos a l comoGNU/Linux para reconocer que el siste-
ma lo compone tanto el ncleo Linux como las bibliotecas de C y
otras herramientas deGNU que hacen posible Linux1.
glibc y gnulib son muy portables y soportan gran cantidad de
plataformas de hardwa-re [5]. En los sistemas Linux se instalan
normalmente con el nombre de libc6 y gnulibrespectivamente. No debe
confundirse con GLib2, otra biblioteca que proporciona estruc-turas
de datos avanzadas como rboles, listas enlazadas, tablas hash, etc.
y un entorno deorientacin a objetos en C.
En estas prcticas utilizaremos la biblioteca glibc como
implementacin de programa-
1http://es.wikipedia.org/wiki/Controversia_por_la_denominaci%C3%B3n_GNU/Linux2http://library.gnome.org/devel/glib/
http://es.wikipedia.org/wiki/Controversia_por_la_denominaci%C3%B3n_GNU/Linuxhttp://library.gnome.org/devel/glib/
-
4 Programacin y Administracin de Sistemas 2011-2012
cin del API POSIX. Algunas distribuciones de GNU/Linux, como
Debian o Ubuntu utilizanuna variante de la glibc llamada eglibc3,
pero a efectos de programacin no debera ha-ber diferencias.
2. Objetivos
Conocer algunas rutinas POSIX y su implementacin glibc.
Aprender a utilizar bibliotecas externas en nuestros
programas.
Aprender cmo funcionan internamente algunas partes de
GNU/Linux.
Mejorar la programacin viendo ejemplos hechos por los
desarrolladores de las biblio-tecas.
Aprender a comunicar aplicaciones en red y conocer brevemente la
arquitectura Cliente-Servidor.
3. Entrega de prcticas
Se pedir la entrega y defensa de algunos ejercicios resmenes que
integren varios de losconceptos y funciones estudiadas en clase.
Las prcticas deben realizarse a nivel individualy se utilizarn
mecanismos para comprobar que se han realizado y entendido.
4. Documentacin de POSIX y las bibliotecas
Documentacin POSIX.1-2008: Especificacin del estndar POSIX.
Dependiendo de la par-te que documente es ms o menos
pedaggica4.
Documentacin GNU C Library: Esta documentacin incluye muchos de
los conceptos queya habis trabajado en asignaturas de introduccin a
la programacin o de sistemasoperativos. Es una gua completa de
programacin en el lenguaje C, pero sobre to-do incluye muchas
funciones que son esenciales para programar, tiles para
ahorrartiempo trabajando o para garantizar la portabilidad del
cdigo entre sistemas POSIX5.
5. Procesado de lnea de comandos tipo POSIX
5.1. Introduccin y documentacin
Los parmetros que procesa un programa en sistemas POSIX deben
seguir un estndarde formato y respuesta esperada6. Un resumen de lo
definido en el estndar es lo siguiente:
3http://www.eglibc.org/home4http://pubs.opengroup.org/onlinepubs/9699919799/5http://www.gnu.org/software/libc/manual/612.1
Utility Argument Syntax,
http://pubs.opengroup.org/onlinepubs/9699919799/
basedefs/V1_chap12.html
http://www.eglibc.org/homehttp://pubs.opengroup.org/onlinepubs/9699919799/http://www.gnu.org/software/libc/manual/http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
-
6. Variables de entorno 5
Una opcin es un guin - seguido de un carcter alfanumrico, por
ejemplo, -o.
Una opcin requiere un parmetro que debe aparecer inmediatamente
despus de laopcin, por ejemplo, para -o lo siguiente: -o parmetro o
-oparmetro.
Las opciones que no requieren parmetros pueden agruparse detrs
de un guin, porejemplo, -lst es equivalente a -t -l -s.
Las opciones puede aparecer en cualquier orden, as -lst es
equivalente a -tls.
Las opciones pueden aparecer muchas veces.
El parmetro -- indica el fin de las opciones en cualquier
caso.
La opcin - a menudo se indica para representar alguna entrada
estndar.
La funcin getopt()7 del estndar ayuda a desarrollar el manejo de
las opciones si-guiendo las directrices POSIX.1-2008. getopt() est
implementada en libc89. Puedes vercdigo de ejemplo comentado en el
fichero ejemplo-getopt.c. El fichero ejemplo-getoptlong.ccontiene
un ejemplo de procesado de rdenes al estilo de GNU (por ejemplo,
--help y -hcomo rdenes compatibles). Este segundo ejemplo no lo
veremos en clase.
5.2. Ejercicios
Descarga el cdigo de ejemplo de getopt() de la documentacin de
glibc10. Lee elcdigo, complalo, ejectalo para comprobar que admite
las opciones de parmetros POSIX.Trata de entender el cdigo y aade
ms opciones (por ejemplo una sin parmetros y otra conparmetros).
Debes consultar la seccin Using the getopt function de la
documentacin11
para saber cmo funciona getopt, qu valores espera y qu
comportamiento tiene.
6. Variables de entorno
6.1. Introduccin y documentacin
Una variable de entorno es un objeto designado para contener
informacin usada poruna o ms aplicaciones. La variables de entorno
se asociacin a toda la mquina, pero tam-bin a usuarios
individuales. Si utilizas bash, puedes consultar las variables de
entorno detu sesin con el comando env. Tambin puedes consultar o
modificar el valor de una varia-ble de forma individual:
$ env$ ...$ echo $LANGes_ES.UTF-8$ export LANG=en_GB.UTF-8
7http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html8http://www.gnu.org/software/libc/manual/html_node/Getopt.html9Notas
sobre portabilidad en
http://www.gnu.org/software/gnulib/manual/gnulib.html#
getopt10http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html11http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.htmlhttp://www.gnu.org/software/libc/manual/html_node/Getopt.htmlhttp://www.gnu.org/software/gnulib/manual/gnulib.html#getopthttp://www.gnu.org/software/gnulib/manual/gnulib.html#getopthttp://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.htmlhttp://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html
-
6 Programacin y Administracin de Sistemas 2011-2012
6.2. Ejercicios
Utilizando la funcin getenv()12, haz un programa que dependiendo
del idioma de lasesin de usuario, imprima un mensaje con su carpeta
personal en castellano o en ingls.Puedes ver cdigo de ejemplo en el
fichero ejemplo-getenv.c.
7. Obtencin de informacin de un usuario/a
7.1. Introduccin y documentacin
En los sistemas operativos la base de datos de usuarios puede
ser local y/o remota. Porejemplo, en GNU/Linux puedes ver los
usuarios y grupos locales en los ficheros /etc/passwdy /etc/group.
Si los usuarios no son locales normalmente se encuentran en una
mquinaremota a la que se accede por un protocolo especfico. Algunos
ejemplos son el servicio deinformacin de red (NIS, Network
Information Service) o el protocolo ligero de acceso a di-rectorios
(LDAP, Lightweight Directory Access Protocol). En la actualizad NIS
apenas se usa yLDAP es el estndar para autenticar usuarios tanto en
sistemas Unix o GNU/Linux comoen sistemas Windows.
En el caso de GNU/Linux, la autenticacin de usuarios la realizan
los mdulos de au-tenticacin PAM (Pluggable Authentication Module).
PAM es un mecanismo de autenticacinflexible que permite abstraer
las aplicaciones del proceso de identificacin. La bsqueda desu
informacin asociada la realiza el servicio NSS (Name Service
Switch), que provee una in-terfaz para configurar y acceder a
diferentes bases de datos de cuentas de usuarios y clavescomo
/etc/passwd, /etc/group, /etc/hosts, LDAP, etc.
POSIX presenta una interfaz para el acceso a la informacin de
usuarios que abstrae alprogramador de dnde se encuentran los
usuarios (en bases de datos locales y/o remotas,con distintos
formatos, etc.). Por ejemplo, la llamada getpwuid() devuelve una
estructuracon informacin de un usuario. El sistema POSIX se encarga
de intercambiar informacincon NSS para conseguir la informacin del
usuario. NSS leer ficheros en el disco duro orealizar consultas a
travs de la red para conseguir esa informacin.
7.2. Ejercicios
Puedes ver las funciones y estructuras de acceso a la informacin
de usuarios/as y gru-pos en los siguientes ficheros de cabecera:
/usr/include/pwd.h /usr/include/grp.h.La funcin getpwnam()13
permite obtener informacin de un usuario/a. Mira el programade
ejemplo de getpwnam() y amplalo para utilizar getgrgid()14 para
obtener el nombredel grupo del usuario a travs del identificador
del grupo. Puedes ver cdigo de ejemplo enel fichero
ejemplo-infousuario.c.
12http://pubs.opengroup.org/onlinepubs/009604599/functions/getenv.html13http://pubs.opengroup.org/onlinepubs/009604599/functions/getpwnam.html
http://www.gnu.org/software/libc/manual/html_node/User-Database.html14http://www.gnu.org/software/libc/manual/html_node/Group-Database.html
http://pubs.opengroup.org/onlinepubs/009604599/functions/getenv.htmlhttp://pubs.opengroup.org/onlinepubs/009604599/functions/getpwnam.htmlhttp://www.gnu.org/software/libc/manual/html_node/User-Database.htmlhttp://www.gnu.org/software/libc/manual/html_node/Group-Database.html
-
9. Creacin de procesos Fork y Exec 7
8. Ejercicio resumen 1 (0.5 punto)
Realizar un programa que obtenga e imprima la informacin de un
usuario (todos loscampos de la estructura passwd) pasado por el
parmetro -u. Si adems se le pasa la opcin-g deber buscar e imprimir
la informacin del grupo del usuario (nmero ID del grupo
ynombre).
Si se le pasa la opcin -e imprimir el mensaje en castellano, y
la opcin -s hace que loimprima en ingls. Si no se le pasa ni -e ni
-s se mirar la variable de entorno LANG paramostrar la informacin.
Por ejemplo, las siguientes llamadas seran vlidas:
# Obtener la informacin de un usuario usando el idioma#
configurado en LANG$ infousuario -u i02samoj# Obtener la informacin
de un usuario forzando el# idioma en castellano$ infousuario -u
i02samoj -e# Obtener la informacin de un usuario aadiendo la#
informacin de su grupo principal e imprimiendo todo en ingls$
infousuario -u i02samoj -s -g
El control de errores debe ser el siguiente:
Asegurar que se pasa el nombre del usuario (tienes un ejemplo de
cmo controlar quese pasa el parmetro de una opcin en el
ejemplo-getopt.c).
Las opciones -e y -s no pueden activarse a la vez.
Sugerencia: empezar por el cdigo de ejemplo ejemplo-getopt.c.
Primero debe pro-cesarse la entrada de comandos para asegurarse que
no falta ninguna opcin esencial (porejemplo el nombre de usuario).
Despus debe ir la lgica del programa dependiendo de lasopciones que
se hayan reconocido. Se pueden hacer funciones para simplificar la
funcinmain. Por ejemplo, una funcin para imprimir la informacin del
usuario en castellano/in-gls a la que se le pase la estructura
struct passwd y una opcin. Una sugerencia para elesquema general
puede ser:
1. Procesar opciones de entrada.
2. Usar la variable de entorno LANG si las flags de las opciones
-e o -s estn a cero.
3. Llamar a una funcin que imprima la informacin de un usuario
en ingls o castellanocon las opciones (login, grupo si/no,
idioma).
9. Creacin de procesos Fork y Exec
9.1. Introduccin y documentacin
En general, en sistemas operativos y lenguajes de programacin,
se llama bifurcacin ofork a la creacin de un subproceso copia del
proceso que llama a la funcin. El subprocesocreado, o proceso hijo,
proviene del proceso originario, o proceso padre. Los procesos
-
8 Programacin y Administracin de Sistemas 2011-2012
pid=fork()
case 0:// hijo
default:// padre
Figura 4: Esquema de llamadas y procesos generados por fork() en
el ejemplo.
resultantes son idnticos, salvo que tienen distinto nmero de
proceso (PID)15. En UNIXotra forma de crear subprocesos es utilizar
tuberas o pipes, las cules son esenciales para lacomunicacin
inter-procesos, por ejemplo:
$ find . -name "*.c" -print | wc -l
En C se crea un subproceso con llamando a la funcin fork()16.
Tienes un pequeomanual y mucho cdigo de ejemplo en [6]. Puedes ver
un cdigo con muchos comentariosen la entrada de Wikipedia17. El
nuevo proceso hereda varias propiedades del proceso padre(variables
de entorno, descriptores de ficheros, etc. ). En esta asignatura no
entraremos enqu sucede internamente a nivel del sistema operativo.
Despus de una llamada exitosa afork habr dos copias del cdigo
original ejecutndose a la vez. En el proceso original, elvalor
devuelto de fork ser el identificador del proceso hijo. En cambio,
en el proceso hijoel valor devuelto por fork ser 0.
9.2. Ejercicios y ejemplos
El listado siguiente (ejemplo-fork.c) es un ejemplo de uso de
fork que controla qutipo de proceso es el que ejecuta el cdigo
utilizando el valor devuelto por la funcin, as co-mo otras
funciones POSIX para obtener informacin de los procesos (puedes ver
un esquemade las subprocesos creados en la Figura 4):
#include #include #include
int main(){
pid_t rf;rf = fork();switch (rf)
15http://www.gnu.org/software/libc/manual/html_node/Processes.html16http://pubs.opengroup.org/onlinepubs/9699919799/17http://es.wikipedia.org/wiki/Bifurcaci%C3%B3n_%28sistema_operativo%29
http://www.gnu.org/software/libc/manual/html_node/Processes.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/http://es.wikipedia.org/wiki/Bifurcaci%C3%B3n_%28sistema_operativo%29
-
9. Creacin de procesos Fork y Exec 9
{case -1:
printf ("No he podido crear el proceso hijo \n");exit(-1);
case 0:printf ("Soy el hijo, mi PID es %d y mi PPID es %d
\n",
getpid(), getppid());sleep (5);break;
default:printf ("Soy el padre, mi PID es %d y el PID de mi hijo
es
%d \n", getpid(), rf);sleep (10);
}
printf ("Final de ejecucin de %d \n", getpid());exit (0);
}
Un ejemplo de llamada a este cdigo sera:
$ ./ejemplo-forkSoy el padre, mi PID es 23455 y el PID de mi
hijo es 23456Soy el hijo, mi PID es 23456 y mi PPID es 23455Final
de ejecucin de 23456Final de ejecucin de 23455
En este ejemplo el proceso padre no queda bloqueado esperando al
hijo, prueba a ponerun valor menor de espera (sleep) para el padre
que para el hijo:
$ ./ejemplo-forkSoy el padre, mi PID es 23437 y el PID de mi
hijo es 23438Soy el hijo, mi PID es 23438 y mi PPID es 23437Final
de ejecucin de 23437$ Final de ejecucin de 23438
Si quisiramos que el proceso padre esperase a que el proceso (o
los procesos) hijos ter-minasen, debemos utilizar la funcin wait18.
El valor devuelto por la funcin wait es elPID del proceso hijo que
se est esperando que termine, si se le ha pasado un PID
comoargumento. Si slo se le pasa &status, wait() espera a que
terminen todos los procesoshijos y devuelve el PID del ltimo
proceso en terminar. Un ejemplo:
#include #include
int main(){pid_t pid;int status, died;
18www.gnu.org/software/libc/manual/html_node/Process-Completion.html
www.gnu.org/software/libc/manual/html_node/Process-Completion.html
-
10 Programacin y Administracin de Sistemas 2011-2012
switch(pid=fork()){case -1: printf("cant fork\n");
exit(-1);case 0 : sleep(2); // cdigo que ejecuta el hijo
exit(3);default: died= wait(&status); // cdigo que ejecuta
el padre}
}
En ocasiones puede interesar ejecutar un programa distinto, no
diferentes partes de l, yse quiere iniciar este segundo proceso
diferente desde el programa principal. La familia defunciones
exec() permiten iniciar un programa dentro de otro programa. En
lugar de crearuna copia del proceso, como fork(), exec() provoca el
reemplazo total del programaque llama a la funcin por el programa
llamado. Por ese motivo se suele utilizar exec()junto con fork(),
de forma que sea un proceso hijo el que cree el nuevo proceso para
queel proceso padre no sea destruido. Podemos ver este mecanismo en
el siguiente cdigo deejemplo:
#include #include #include #include
int main(){
pid_t pid;int status, died;
char *args[] = {"/bin/ls", "-r", "-t", "-l", (char *) 0 };
switch(pid=fork()){case -1:
printf("cant fork\n");exit(-1);
case 0 :printf("child\n"); // cdigo que ejecuta el
hijoexecv("/bin/ls", args);
default:died= wait(&status); // cdigo que ejecuta el
padre
}
return(0);}
-
10. Seales entre procesos 11
10. Seales entre procesos
10.1. Introduccin y documentacin
Las seales entre programas son interrupciones software que se
generan para informara un proceso de la ocurrencia de un evento.
Otras formas alternativas o complementarias decomunicacin entre
procesos son las tuberas POSIX (funciones popen y relacionadas) y
laslas colas de mensajes POSIX o POSIX message queues (funciones
mq_open, mq_send. . . ). Losprogramas pueden disearse para capturar
una o varias seales proporcionando una fun-cin que las maneje. Este
tipo de funciones se llaman tcnicamente callbacks o
retrollamadas.Una callback es una referencia a un trozo de cdigo
ejecutable, normalmente una funcin,que se pasa como parmetro a otro
cdigo. Esto permite, por ejemplo, que una capa de bajonivel del
software llame a la subrutina o funcin definida en una capa
superior (ver Figura5, fuente Wikipedia19).
Application program
Software library
Main program
Library function
callsCallback function
calls
Figura 5: Esquema del funcionamiento de las callbacks o
retrollamadas.
Por ejemplo, cuando se apaga GNU/Linux, se enva la seal SIGTERM
a todos los proce-sos, as los procesos pueden capturar esta seal y
terminar de forma adecuada, por ejemploliberando recursos, cerrando
ficheros abiertos, etc. La funcin signal20 permite asociar
unadeterminada funcin (a travs de un puntero a funcin) a una seal
identificada por un en-tero (SIGTERM, SIGKILL, etc.).
#include
sighandler_t signal(int signum, sighandler_t handler);...
10.2. Ejercicios y ejemplos
El cdigo de ejemplo ejemplo-signals.c21 contiene ejemplos
captura de seales PO-SIX enviadas a un programa. Recuerda que la
funcin signal() no llama a ninguna funcin,
19http://en.wikipedia.org/wiki/Callback_%28computer_science%2920http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html21Fuente
http://www.amparo.net/ce155/signals-ex.html
http://en.wikipedia.org/wiki/Callback_%28computer_science%29http://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.htmlhttp://www.amparo.net/ce155/signals-ex.html
-
12 Programacin y Administracin de Sistemas 2011-2012
lo que hace es asociar una funcin del programador a eventos que
se generan en el sistema,esto es, pasar un puntero a una
funcin.
$ ./ejemplo-signalCannot handle SIGKILL!I caught the SIGHUP
signal!I caught the SIGTERM signal!Terminado (killed)# En otra
terminal: obtener el PID del proceso$ ps -e|grep signal31188 pts/0
00:00:05 ejemplo-signal$ kill -SIGHUP 31188$ killall ejemplo-signal
# mandamos seal SIGTERM$ killall ejemplo-signal -9 # Forzamos parar
el programa con
SIGKILL
11. sockets POSIX
11.1. Introduccin y conceptos bsicos
En esta seccin haremos una pequea introduccin a los sockets
POSIX, una herra-mienta que permite desarrollar aplicaciones que se
comuniquen entre s a travs de una redutilizando diferentes
protocolos o facilitando el desarrollo de otros protocolos sobre
TCP/IP.Como esta no es una asignatura especfica de redes,
aprenderemos algunos conceptos y al-goritmos bsicos para la
comunicacin pero sin entrar en detalle del funcionamiento y detodas
las opciones disponibles. Si tienes duda sobre alguna funcin, hay
un buen resumenen castellano con los pasos y funciones para
utilizar sockets en la web chuidiang.com [7],nosotros usaremos
algunas descripciones de este manual por ser muy sencillas y
claras. Acontinuacin daremos algunas definiciones.
Protocolo: En una red de ordenadores hay varios ordenadores que
estn conectados entre sipor un medio fsico (cable, ondas
inalmbricas, etc.) a travs del cul puede transmitir-se informacin.
Para que exista esta comunicacin debe haber un idioma o
protocolocomn entre los equipos. Hay muchsimos protocolos de
comunicacin, entre los cua-les el ms extendido es el TCP/IP. El ms
extendido porque es el que se utiliza enInternet.
socket: Un socket no es ms que un canal de comunicacin entre dos
programas quecorren sobre ordenadores distintos o incluso en el
mismo ordenador. Desde el puntode vista de programacin, un socket
no es ms que un fichero que se abre de unamanera especial. Una vez
abierto se pueden escribir y leer datos de l con las
habitualesfunciones de read() y write() del lenguaje C. Existen
bsicamente dos tipos decanales de comunicacin o sockets, los
orientados a conexin (por ejemplo TCP)y los no orientados a conexin
(por ejemplo UDP). Nosotros veremos un ejemplo defuncionamiento de
sockets orientados a la conexin.
arquitectura cliente-servidor: La arquitectura cliente-servidor
es un modelo de aplicacindistribuida en el que las tareas se
reparten entre los proveedores de recursos o servicios,
-
11. sockets POSIX 13
llamados servidores, y los demandantes, llamados clientes. Por
ejemplo, la World WideWeb (WWW) se implementa con este modelo. El
servidor es el programa que permanecepasivo a la espera de que
alguien solicite conexin con l, normalmente, para pedirlealgn dato.
Cliente es el programa que solicita la conexin para, normalmente,
pedirdatos al servidor.
11.2. Algoritmo bsico Cliente-Servidor
La Figura 6 muestra el diagrama de flujo general de la
comunicacin Cliente-Servidorutilizando sockets.
Servidor
socket()
connect()
send()
recv()
closeSocket()
Cliente
socket()
bind()
listen()
accept()
recv()
send()
recv()
closeSocket()
El cliente enva datos yel servidor los recive
El servidor enva datos y el cliente los recive
El cliente manda un mensaje para finalizar la conexin
Diagrama de flujode un socket TCPimplementando el
modeloCliente-Servidor
Figura 6: Diagrama de flujo de la implementacin del modelo
Cliente-Servidor orientado ala conexin con sockets POSIX.
-
14 Programacin y Administracin de Sistemas 2011-2012
11.3. Pasos de programacin C en el lado Servidor
Con C en Unix/Linux, los pasos que debe seguir un programa
servidor son los siguientes[7]:
Apertura de un socket, mediante la funcin socket(). Esta funcin
devuelve un des-criptor de fichero normal, como puede devolverlo
open() o fopen(). La funcinsocket() no hace absolutamente nada
respecto a iniciar la comunicacin, salvo de-volvernos y preparar un
descriptor de fichero que el sistema posteriormente asociara una
conexin en red.
Avisar al sistema operativo de que hemos abierto un socket y
queremos que asocienuestro programa a dicho socket. Se consigue
mediante la funcin bind(). El siste-ma todava no atender a las
conexiones de clientes, simplemente anota que cuandoempiece a
hacerlo, tendr que avisarnos a nosotros. Es en esta llamada cuando
se debeindicar el nmero de servicio (o puerto) al que se quiere
atender.
Avisar al sistema de que comience a atender dicha conexin de
red. Se consigue me-diante la funcin listen(). A partir de este
momento el sistema operativo anotarla conexin de cualquier cliente
para pasrnosla cuando se lo pidamos. Si llegan clien-tes ms rpido
de lo que somos capaces de atenderlos, el sistema operativo hace
unacola con ellos y nos los ir pasando segn vayamos pidindolo.
Pedir y aceptar las conexiones de clientes al sistema operativo.
Para ello hacemos unallamada a la funcin accept(). Esta funcin le
indica al sistema operativo que nos dal siguiente cliente de la
cola. Si no hay clientes se quedar bloqueada hasta que algncliente
se conecte.
Escribir y recibir datos del cliente, por medio de las funciones
write() y read(), queson exactamente las mismas que usamos para
escribir o leer de un fichero. Obviamente,tanto cliente como
servidor deben saber qu datos esperan recibir, qu datos debenenviar
y en qu formato, por ejemplo el protocolo HTTP y el formato HTML o
XHTML.
Cierre de la comunicacin y del socket, por medio de la funcin
close(), que es lamisma que sirve para cerrar un fichero.
11.4. Pasos de programacin C en el lado Cliente
Nosotros no veremos la parte del cliente, ya que cualquier
navegador web ser el clientede nuestro servidor. Los pasos que debe
seguir un programa cliente son los siguientes [7]:
Apertura de un socket, como el servidor, por medio de la funcin
socket().
Solicitar conexin con el servidor por medio de la funcin
connect(). Dicha funcinquedar bloqueada hasta que el servidor
acepte nuestra conexin o bien si no hayservidor en el sitio
indicado, saldr dando un error. En esta llamada se debe facilitar
ladireccin IP del servidor y el nmero de servicio que se desea.
Escribir y recibir datos del servidor por medio de las funciones
write() y read().
Cerrar la comunicacin por medio de close().
-
12. Todo junto: un servidor web bsico en C 15
Figura 7: Ejemplo de ejecucin del servidor web con la llamada
ejemplo-webserver -p8080 -r htdocs
12. Todo junto: un servidor web bsico en C
12.1. Introduccin y cdigo
En esta seccin vamos a ver un ejemplo que combina muchas de las
funciones POSIXque hemos visto en las prcticas. Esta seccin la
trabajaremos directamente sobre el cdigode ejemplo
ejemplo-webserver.c. Este ejemplo es un cdigo ampliado descargado
deinternet con algunas funciones auxiliares que se han aadido para
facilitar los ejercicios.Pregunta todas las dudas que tengas
durante la explicacin del cdigo. El objetivo es tratarde reconocer
los pasos del modelo Cliente-Servidor de la Figura 6 a grandes
rasgos y sinperderse en los detalles, ya que no se pedir ninguna
modificacin de las partes de cdigorelativas a la comunicacin.. La
Figura 8 muestra el funcionamiento general del cdigo delservidor
web combinando el esquema de la Figura 6 con fork() para poder
atender variasconexiones de manera simultnea.
-
16 Programacin y Administracin de Sistemas 2011-2012
Servidor
socket()
connect()
send()
recv()
closeSocket()
Cliente
socket()
bind()
listen()
accept()
recv()
send()
recv()
closeSocket()
HTTP/1.0 200 OK....Datos
El cliente manda un mensaje para finalizar la conexin
Diagrama de flujodel ejemplo de servidor web bsico
startServer()
while(1) { ... fork() ...}
respond()
fork()
GET /hola.html HTTP/1.1
La llamada a accept() crea un nuevosocket para atender la
conexinque deber ser cerrado al finalizarel intercambio de
datos.
El socket creado por el procesoprincipal debera ser cerradoal
finalizar el programa, por ejemplo capturando lasseales SIGTERM,
SIGINT...
Figura 8: Diagrama de flujo de la implementacin del modelo
Cliente-Servidor orientado ala conexin con sockets POSIX.
12.2. Ejercicios
Arranca y para el servidor siguiendo la ayuda de la lnea de
comandos. Prueba a conec-tarte a l a travs del navegador y prueba a
cambiar las opciones. Si no sabes HTML, miralos ficheros de ejemplo
del directorio htdocs del paquete de prcticas.
Para arrancar el servidor, que escuche en el puerto 8080 y que
utilice el directorio htdocscomo raz para servir ficheros web:
$ ./ejemplo-webserver -p 8080 -r htdocs
ahora visita la direccin http://localhost:8080/ y comprueba que
puedes navegar porlas pginas alojadas en el servidor. En el
navegador deberas obtener un resultado similar alde la Figura 7.
Puedes probar a ejecutar el servidor en ts.uco.es, en este caso la
direccin
http://localhost:8080/
-
13. Ejercicio resumen 2 (1 punto) 17
sera http://ts.uco.es:8080/. Si esto lo hacis varias personas,
tal vez tengis quecambiar el puerto porque slo una aplicacin puede
escuchar en un puerto, este mensajede error os indicara que ya hay
una aplicacin asociada al puerto que pretendis usar:
$ ./ejemplo-webserver -p 8080 -r htdocs$ socket() or bind():
Address already in use
Este mensaje de error puede obtenerse an cuando haya finalizado
la ejecucin de pro-grama que escucha el puerto. Aunque el documento
es antiguo y la explicacin tal vez nosea precisa, puedes leer una
explicacin de por qu pasa esto en [8]
13. Ejercicio resumen 2 (1 punto)
Para este ejercicio partiremos del cdigo ejemplo-webserver.c. El
Makefile del pa-quete de prcticas ya incluye una regla para
compilar el fichero webserverex.c. Ejercicios:
1. La funcin webServerLog() implementa un pequeo sistema de
registro o log (noptimo, por supuesto). Esta funcin es similar a
printf(). Utilizndola se puedenregistrar mensajes de inicio o
parada del servidor o los accesos al servidor en el
ficheroaccess.log y los errores en el fichero error.log. Por
ejemplo, puedes hacer lassiguientes llamadas:
webServerLog(WS_LOG_ACCESS, \"Servidor iniciado en el puerto
%s", PORT);
webServerLog(WS_LOG_ERROR, "Error en la conexin");
No necesitas reemplazar todos los mensajes, pero si los ms
significativos: cuando nose puede iniciar el servidor por estar el
puerto ocupado, el inicio o parada del servidory las peticiones
HTTP que llegan al servidor.
2. Modifica el cdigo del servidor web para que tenga una nueva
opcin -f. Cuando sepase esta opcin, el servidor deber incluir una
foto del Fary en todas las pginas webque sirva. Una imagen se
incluye en HTML con el cdigo insertado entre las eti-quetas y , que
es donde va el contenido en si de una pgina HTML.
Figura 9: El Fary
http://ts.uco.es:8080/
-
18 Programacin y Administracin de Sistemas 2011-2012
Ten en cuenta que el navegador har una peticin por cada fichero
.html, y otra(s) porcada imagen (u otros datos) contenidos en la
web. As, si una web tiene una imagen,el navegador pedir primero el
fichero .html con un GET /hola.html HTTP/1.1 ycuando lo abra y
detecte la etiqueta har otra peticin GET /fichero.jpgHTTP/1.1 para
que el servidor le enve el fichero de la imagen22. Aydate y
modificasi lo necesitas las funciones auxiliares strcasestr()23 y
copyfile(). Acurdate deactualizar la ayuda del programa.
3. Captura algunas llamadas al sistema (SIGTERM, SIGINT y
SIGHUP) para gestionar elfin del programa adecuadamente. Puedes
asociar estas tres seales con la misma fun-cin de parar el
servidor. Se deberan finalizar y cerrar adecuadamente las
conexionesy ficheros abiertos. Opcionalmente puedes hacer un script
de bash que arranque y pareel servidor ejecutando el servidor y
envindole la seal SIGTERM respectivamente. Porejemplo,
start-server.sh y stop-server.sh.
4. Captura la URL solicitada por el cliente. Si se pide la URL
http://servidor:puerto/infousuario/i02samoj el servidor debe
generar una web con la informacin delusuario. Con el cdigo del
ejercicio resumen 1 y usando un fichero temporal no debe-ra ser muy
difcil.
Para el segundo ejercicio, una llamada similar a
$ ./ejemplo-webserver -p 8080 -r htdocs/ -f
debera producir un resultado similar en el navegador al de la
Figura 10.
14. Trabajo futuro
Algunas ideas que no ha dado tiempo a hacer:
Utilizar el patrn de diseo singleton para guardar la
configuracin del programa.
Controlar la destruccin de subprocesos del servidor pasado un
tiempo.
Comunicacin inter-procesos con diferentes alternativas (tuberas,
POSIX MQ, etc.).
Capturar cmo ha muerto un proceso WEXITSTATUS, WTERMSIG...
Hacer que el servidor sirva cdigo generado con PHP (por ejemplo
recogiendo la salidade php ejemplo.php)
22La peticin de estos ficheros auxiliares se hace al servidor
que sirve la web, pero tambin se puede hacer aotro si el fichero se
encuentra en otro sitio web. Esto ocurre por ejemplo cuando se
inserta un vdeo de youtube osimilares en una pgina.
23En el cdigo del servidor web se proporciona la funcin
strcasestr(cadena, subcadena) para facili-tar uno de los
ejercicios. Esta funcin busca una subcadena dentro de una cadena.
Devuelve un 0 si no encuentrala subcadena o la posicin de la
subcadena si la encuentra, es decir, un valor mayor que cero.
http://servidor:puerto/infousuario/i02samojhttp://servidor:puerto/infousuario/i02samoj
-
14. Trabajo futuro 19
Figura 10: Ejemplo del resultado de la ejecucin del servidor web
para implementar la op-cin -f.
-
20 Programacin y Administracin de Sistemas 2011-2012
Referencias
[1] Wikipedia. Posix wikipedia, la enciclopedia libre, 2012.
[Internet; descargado 12-abril-2012]. Available from:
http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603.
[2] The IEEE and The Open Group. Posix.1-2008 the open group
base specifications issue 7,2008. Available from:
http://pubs.opengroup.org/onlinepubs/9699919799/.
[3] Proyecto GNU. Gnu c library, 2012. Available from:
http://www.gnu.org/software/libc/libc.html.
[4] Brian W. Kernighan, Dennis Ritchie, and Dennis M. Ritchie. C
Programming Language(2nd Edition). Pearson Educacin, 2 edition,
1991.
[5] Wikipedia. Glibc wikipedia, la enciclopedia libre, 2012.
[Internet; descargado 12-abril-2012]. Available from:
http://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698.
[6] Tim Love. Fork and exec, 2008. Available from:
http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.html.
[7] chuidiang.com. Programacin de sockets en c de unix/linux,
2007. Available
from:http://www.chuidiang.com/clinux/sockets/sockets_simp.php.
[8] Andrew Gierth Vic Metcalfe and other contributers.
Programming UNIX Sockets inC - Frequently Asked Questions. 4.2 Why
dont my sockets close?, 1996. Availa-ble from:
http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2.
[9] Wikipedia. Dennis ritchie wikipedia, la enciclopedia libre,
2012. Available from:
http://es.wikipedia.org/wiki/Dennis_Ritchie.
http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603http://es.wikipedia.org/w/index.php?title=POSIX&oldid=53746603http://pubs.opengroup.org/onlinepubs/9699919799/http://www.gnu.org/software/libc/libc.htmlhttp://www.gnu.org/software/libc/libc.htmlhttp://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698http://es.wikipedia.org/w/index.php?title=Glibc&oldid=53229698http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.htmlhttp://www-h.eng.cam.ac.uk/help/tpl/unix/fork.htmlhttp://www.chuidiang.com/clinux/sockets/sockets_simp.phphttp://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-4.html#ss4.2http://es.wikipedia.org/wiki/Dennis_Ritchiehttp://es.wikipedia.org/wiki/Dennis_Ritchie
1 Introduccin a POSIX2 Objetivos3 Entrega de prcticas4
Documentacin de POSIX y las bibliotecas5 Procesado de lnea de
comandos tipo POSIX5.1 Introduccin y documentacin5.2 Ejercicios
6 Variables de entorno6.1 Introduccin y documentacin6.2
Ejercicios
7 Obtencin de informacin de un usuario/a7.1 Introduccin y
documentacin7.2 Ejercicios
8 Ejercicio resumen 1 (0.5 punto)9 Creacin de procesos Fork y
Exec9.1 Introduccin y documentacin9.2 Ejercicios y ejemplos
10 Seales entre procesos10.1 Introduccin y documentacin10.2
Ejercicios y ejemplos
11 sockets POSIX11.1 Introduccin y conceptos bsicos11.2
Algoritmo bsico Cliente-Servidor11.3 Pasos de programacin C en el
lado Servidor11.4 Pasos de programacin C en el lado Cliente
12 Todo junto: un servidor web bsico en C12.1 Introduccin y
cdigo12.2 Ejercicios
13 Ejercicio resumen 2 (1 punto)14 Trabajo futuroReferencias