Provided by:
manpages-es_1.55-8_all 
NOMBRE
accept - acepta una conexión sobre un conector (socket).
SINOPSIS
#include <sys/types.h>
#include <sys/socket.h>
int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
DESCRIPCIÓN
La función accept se usa con conectores orientados a conexión
(SOCK_STREAM, SOCK_SEQPACKET y SOCK_RDM). Extrae la primera petición
de conexión de la cola de conexiones pendientes, le asocia un nuevo
conector con, practicamente, las misma propiedades que s y reserva un
nuevo descriptor de fichero para el conector, el cuál es el valor
devuelto por la llamada. El conector original s no se ve afectado por
esta llamada. Dese cuenta que cualquier opción por descriptor de
fichero (cualquiera que se pueda establecer con F_SETFL de fcntl, como
no bloqueante o estado asÃncrono) no se hereda en un accept.
El argumento s es un conector que ha sido creado con socket(2), ligado
a una dirección local con bind(2) y que se encuentra a la escucha tras
un listen(2).
El argumento addr es un puntero a una estructura sockaddr. Esta
estructura se rellena con la dirección de la entidad con la que se
conecta, tal y como la conoce la capa de comunicaciones. El formato
exacto de la dirección pasada en el parámetro addr viene determinado
por la familia del conector (vea socket(2) y las páginas de manual del
protocolo correspondiente). El argumento addrlen es un parámetro de
entrada/salida: al efectuar la llamada debe contener el tamaño de la
estructura apuntada por addr; a la salida, contendrá la longitud real
(en bytes) de la dirección devuelta. Cuando addr es NULL nada se
rellena.
Si no hay conexiones pendientes en la cola y el conector no está
marcado como "no bloqueante", accept bloqueará al invocador hasta que
se presente una conexión. Si el conector está marcado como no
bloqueante y no hay conexiones pendientes en la cola, accept devolverá
EAGAIN.
Para ser informado de las conexiones entrantes que se produzca en un
conector, puede usar select(2) o poll(2). Se producirá un evento de
lectura en el intento de una nueva conexión y entonces puede llamar a
accept para obtener un conector para esa conexión. Alternativamente,
puede configurar el conector para que provoque una señal SIGIO cuando
se produzca actividad en el conector; vea socket(7) para más detalles.
Para determinados protocolos que necesitan una confirmación explÃcita,
tales como DECNet, accept se puede interpretar como una función que,
simplemente, desencola la siguiente petición de conexión sin que ello
implique la confirmación. Se sobreentiende la confirmación cuando se
produce una lectura o escritura normal sobre el nuevo descriptor de
fichero, y el rechazo puede ser de igual manera implÃcito cerrando el
nuevo conector. Actualmente, sólo DECNet tiene esta semántica en Linux.
OBSERVACIONES
Puede que no siempre haya una conexión esperando después de que se
produzca una señal SIGIO, o después de que select(2) o poll(2)
devuelvan un evento de lectura, debido a que la conexión podrÃa haber
sido eliminada por un error asÃncrono de red u otro hilo antes de que
se llame a accept. Si esto ocurre entonces la llamada se bloqueará
esperando a que llegue la siguiente conexión. Para asegurarse de que
accept nunca se bloquea, es necesario que el conector s pasado tenga la
opción O_NONBLOCK activa (vea socket(7)).
VALOR DEVUELTO
La llamada devuelve -1 ante un error. Si tiene éxito, devuelve un
entero no negativo que es el descriptor del conector aceptado.
MANEJO DE ERRORES
La llamada accept de Linux pasa los errores de red ya pendientes sobre
el nuevo conector como un código de error de accept. Este
comportamiento difiere de otras construcciones de conectores BSD. Para
un funcionamiento fiable, la aplicación debe detectar los errores de
red definidos por el protocolo tras una llamada a accept y tratarlos
como EAGAIN reintentado la operación. En el caso de TCP/IP estos son
ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH,
EOPNOTSUPP y ENETUNREACH.
ERRORES
accept fallará si:
EAGAIN o EWOULDBLOCK
El conector está marcado como no-bloqueante y no hay conexiones
que aceptar.
EBADF El descriptor es inválido.
ENOTSOCK
El descriptor referencia a un fichero, no a un conector.
EOPNOTSUPP
El conector referenciado no es del tipo SOCK_STREAM.
EINTR La llamada al sistema fue interrumpida por una señal que fue
capturada antes de que llegara una conexión válida.
ECONNABORTED
Una conexión fue abortada.
EINVAL El conector no está escuchando conexiones.
EMFILE El lÃmite de descriptores de fichero abiertos por proceso ha
sido alcanzado.
ENFILE El lÃmite máximo del sistema para descriptores de fichero ha
sido alcanzado.
accept puede fallar si:
EFAULT El parámetro addr no se encuentra en una zona accesible para
escritura por el usuario.
ENOBUFS, ENOMEM
No hay suficiente memoria disponible. Esto normalmente
significa que la asignación de memoria está limitada por los
lÃmites del buffer de conectores, no por la memoria del sistema.
EPROTO Error de protocolo.
La llamada accept de Linux puede fallar si:
EPERM Las reglas del cortafuegos prohÃben la conexión.
Además, se pueden devolver otros errores de red para el nuevo conector
y que se encuentren definidos en el protocolo. Diferentes núcleos de
Linux pueden devolver otros errores diferentes como ENOSR,
ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT. El valor ERESTARTSYS
puede darse durante una ejecución paso a paso.
CONFORME A
SVr4, 4.4BSD (la función accept apareció por primera vez en BSD 4.2).
La página de manual de BSD documenta cinco posibles respuestas de error
(EBADF, ENOTSOCK, EOPNOTSUPP, EWOULDBLOCK, EFAULT). SUSv3 documenta
los errores EAGAIN, EBADF, ECONNABORTED, EINTR, EINVAL, EMFILE, ENFILE,
ENOBUFS, ENOMEM, ENOTSOCK, EOPNOTSUPP, EPROTO, EWOULDBLOCK. Además,
SUSv2 documenta EFAULT y ENOSR.
La llamada accept de Linux no hereda opciones de conector como
O_NONBLOCK. Este comportamiento difiere de otras construcciones de
conectores BSD. Los programas portables no deben confiar en este
comportamiento y establecer siempre todas las opciones requeridas en el
conector devuelto por accept.
NOTA
El tercer argumento de accept se declaró originalmente como un ‘int *’
(y asà está en libc4 y libc5 y en otros muchos sistemas como BSD 4.*,
SunOS 4, SGI); el estándar propuesto POSIX 1003.1g quiso cambiarlo a
‘size_t *’ y asà está en SunOS 5. Más tarde, los borradores POSIX
tenÃan ‘socklen_t *’ y asà lo tomaron the Single Unix Specification y
glibc2. Citando a Linus Torvalds: _Cualquier_ biblioteca razonable
_debe_ hacer que "socklen_t" sea del mismo tamaño que int. Cualquier
otra cosa destroza todo lo de la capa de conectores BSD. POSIX
inicialmente estableció el tipo a size_t y, de hecho, yo (y es de
suponer que otros aunque, obviamente, no demasiados) nos quejamos a
gritos. El ser de tipo size_t es completamente desastroso, precisamente
porque, por ejemplo, size_t muy rara vez es del mismo tamaño que "int"
en arquitecturas de 64 bit. Y _tiene_ que ser del mismo tamaño que
"int" porque asà está en la interfaz de conectores BSD. De cualquier
modo, los de POSIX finalmente tuvieron una idea y crearon "socklen_t".
Para empezar, no deberÃan haberlo tocado pero, una vez que lo hicieron,
pensaron que debÃan tener un tipo con nombre propio por alguna
insondable razón (probablemente alguien no querÃa desprestigiarse por
haber cometido la estupidez original por lo que, simplemente,
renombraron su metedura de pata de forma silenciosa).
VÉASE TAMBIÉN
bind(2), connect(2), listen(2), select(2), socket(2)