telnet
. Este programa es el que se encarga
de recoger los caracteres que tecleáis desde vuestros terminales
de la red y pasarlos al teminal local del servidor. Y al contrario,
cuando el terminal local del servidor da caracteres, el programa
se encarga de reemitirlos por la red para que os lleguen a
vosotros. Esto hace que el programa tenga que quedarse
bloqueado esperando por dos sucesos: la llegada de un
carácter pulsado por vosotros a través de la red o la
llegada de salida de los programas que estéis ejecutando.
select
.select
es:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);A estas alturas de curso, con la página de manual y el resumen tenéis que ser capaces de usar una llamada al sistema. Solamente os daré unos apuntes acerca de
select
. A select
se le ha de proporcionar tres conjuntos de
descriptores de ficheros. El primer conjunto especificará
los descriptores de ficheros sobre los que queremos ser
informados cuando haya datos para leer de ellos. En el
segundo incluiremos aquellos descriptores sobre los
que queremos ser informados cuando se pueda escribir
en ellos sin quedarnos bloqueados (p. ej. tubería llena).
En el último conjunto están los descriptores de los que
seremos informados cuando haya sobre ellos condición
de error.
fd_set
. Además,
debemos disponer de unas funciones para actuar sobre este
tipo. Son las funciones de biblioteca FD_ZERO
,
FD_SET
y FD_CLR
, que vienen en
el resumen. También allí se
puede ver el significado del último parámetro.
select
se quede
bloqueado hasta que lleguen caracteres por la entrada
estándar o la tubería cuyo descriptor tenemos en la
variable fd
, la llamada tendría los
siguientes parámetros:
fd+1
(este parámetro es el número más
alto de descriptor que se comprobará más uno. Como la
entrada estándar es el 0, será fd+1
.
fd_set
.
NULL
, no nos preocupa la posibilidad de
escritura.
NULL
, no nos preocupan los errores.
NULL
, pues queremos que select
se bloquee indefinidamente.
select
vuelva, si ha tenido éxito y hay
datos que leer, nos devolverá cuántos descriptores requieren
nuestra atención. En el ejemplo, puede devolver 1 ó 2. Además,
select
habrá dejado en los conjuntos que
le hayamos pasado sólo aquellos descriptores que requieran
atención. Por consiguiente, no podemos volver a usar
el mismo conjunto para llamar otra vez a select
.
Hay que refrescarlo.
select
.select
es aquel sobre el que
queremos esperar hasta que haya algún dato que leer. Hay una
pequeña excepción. Cuando se alcanza el final de un
fichero (o se corta la comunicación en una tubería o un
socket), select
se desbloquea si el objeto está
entre los especificados en su primer conjunto de descriptores
de fichero. Ya sabemos que al hacer un read
sobre uno de ellos, la llamada al sistema devolverá cero
inmediatamente, señal que nos sirve para detectar el fin del
fichero o el corte de la comunicación.
select
volverá y señalará un descriptor
de su primer/segundo conjunto cuando puede garantizar que
una llamada a read
/write
no se
va a quedar bloqueada sobre él.
[[x segundos]]
",
siendo x el número de segundos que han transcurrido.
El programa padre atenderá a la entrada estándar y a
la tubería. Por cualquier medio que le llegue algo,
escribirá lo que le llegue en el fichero que se le
ha pasado por la línea
de órdenes. Cuando el usuario presione CTRL+D
,
el programa
acabará, no sin antes haber matado todos los procesos.
Se puede usar sleep
en el hijo. Haced todo
el programa en un único fichero fuente .c
.
FD_ZERO
, FD_SET
,
FD_CLR
fd_set