Provided by: manpages-pl-dev_20051117-1_all bug

NAZWA

       accept - przyjmowanie połączenia na gnieździe

SKŁADNIA

       #include <sys/types.h>
       #include <sys/socket.h>

       int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

OPIS

       Funkcja   accept   jest   używana   z   połączeniowymi   typami  gniazd
       (SOCK_STREAM, SOCK_SEQPACKET i SOCK_RDM).  Wyciąga ona pierwsze żądanie
       połączenia  z  kolejki  oczekujących  połączeń,  tworzy nowo podłączone
       gniazdo o tych samych właściwościach co s  i  alokuje  nowy  deskryptor
       pliku  dla  gniazda,  który to deskryptor jest zwracany. Nowo utworzone
       gniazdo nie jest już w  stanie  nasłuchiwania.   Oryginalne  gniazdo  s
       pozostaje po wywołaniiu funkcji niezmienione. Należy zauważyć, że żadne
       znaczniki dotyczące deskryptora pliku (wszystko, co  można  ustawić  za
       pomocą  F_SETFL,  jak  stan  nieblokujący  czy  asynchroniczny)  nie są
       poprzez accept dziedziczone.

       Argument s jest gniazdem, które zostało utworzone wywołaniem socket(2),
       przywiązanym  do  adresu  lokalnego  z  pomocą bind(2), i nasłuchującym
       połączeń po wywołaniu listen(2).

       Argument addr jest wskaźnikiem do struktury sockaddr. Do struktury  tej
       jest  wpisywany  adres łączącej się jednostki, przekazany przez warstwę
       komunikacyjną. Dokładny format adresu przekazywanego w parametrze  addr
       jest  określony  poprzez  rodzinę  gniazda  (zobacz  socket(2) i strony
       podręcznika dotyczące odpowiedniego protokołu).  Argument addrlen  jest
       parametrem  wartościowo-wynikowym: powinien początkowo zawierać rozmiar
       struktury, na którą  wskazuje  addr;  po  zakończeniu  będzie  zawierał
       rzeczywistą  długość zwracanego adresu (w bajtach). Gdy addr jest równe
       NULL, to nic nie jest wypełniane.

       Jeśli nie ma zalegających  połączeń  w  kolejce,  a  gniazdo  nie  jest
       zaznaczone jako nieblokujące, to accept blokuje proces wywołujący aż do
       uzyskania połączenia. Gdy gniazdo jest zaznaczone jako  nieblokujące  i
       nie ma zalegających połączeń w kolejce, accept zwraca EAGAIN.

       Aby  być  informowanym  o  nadchodzących do gniazda połączeniach, można
       użyć select(2) lub poll(2).  Podczas próby nowego  połączenia  zostanie
       dostarczone  zdarzenie odczytywalności (readable) i wtedy można wywołać
       accept aby uzyskać gniazdo  tego  połączenia.  Inaczej,  można  ustawić
       gniazdo  tak,  by dostarczało SIGIO za każdym razem, gdy się na nim coś
       zacznie dziać; szczegóły można znaleźć w socket(7).

       Dla niektórych protokołów  wymagających  bezpośredniego  potwierdzania,
       takich  jak  DECNet,  accept  może  być uważane za funkcję zdejmującą z
       kolejki  następne  żądanie  połączenia,  nie  powodując  potwierdzenia.
       Potwierdzenie  można  spowodować  przez  normalny  odczyt, lub zapis na
       nowym deskryptorze pliku,  a  odrzucenie  można  spowodować,  zamykając
       gniazdo. Obecnie pod Linuksem taką semantykę ma tylko DECNet.

UWAGI

       Nie zawsze po dostarczeniu SIGIO musi istnieć oczekujące połączenie. To
       samo   dotyczy   select(2)   i    poll(2),    zwracających    zdarzenie
       odczytywalności,   ponieważ  połączenie  mogło  zostać  usunięte  przez
       asynchroniczny błąd sieci lub  inny  wątek,  przed  wywołaniem  accept.
       Jeśli to się zdarzy, to wywołanie będzie blokować, oczekując następnego
       połączenia.  Aby upewnić się, że accept nigdy nie będzie  blokowało,  s
       powinno mieć ustawiony znacznik O_NONBLOCK (zobacz socket(7)).

WARTOŚĆ ZWRACANA

       Wywołanie  w  przypadku  błędu  zwraca  -1.  Gdy zakończy sie pomyślnie
       zwraca nieujemną liczbę całkowitą, która jest  deskryptorem  przyjętego
       gniazda.

OBSŁUGA BŁĘDÓW

       Linuksowe  accept  przekazuje  zalegające  już na nowym gnieździe błędy
       sieciowe  jako  kod  błędu  z  accept.   Zachowanie  to  różni  się  od
       implementacji gniazd w BSD. Dla sensownego działania, aplikacja powinna
       wykrywać po wykonaniu accept błędy sieciowe,  zdefiniowane  dla  danego
       protokołu  i  traktować  je jak EAGAIN, czyli ponawiać próbę. W wypadku
       TCP/IP  są  to  ENETDOWN,  EPROTO,  ENOPROTOOPT,   EHOSTDOWN,   ENONET,
       EHOSTUNREACH, EOPNOTSUPP i ENETUNREACH.

BŁĘDY

       Funkcja accept musi zakończyć się niepomyślnie gdy:

       EAGAIN lub EWOULDBLOCK
              Gniazdo  jest zaznaczone jako nieblokujące a brak jest połączeń,
              które mogłyby zostać przyjęte.

       EBADF  Deskryptor jest nieprawidłowy.

       ENOTSOCK
              Deskryptor odnosi się do pliku, zamiast do gniazda.

       EOPNOTSUPP
              Przekazane gniazdo nie jest typu SOCK_STREAM.

       EINTR  Funkcja systemowa została przerwana  wskutek  odebrania  sygnału
              przed prawidłowym nawiązaniem połączenia.

       ECONNABORTED
              Połączenie zostało przerwane.

       EINVAL Gniazdo nie nasłuchuje połączeń.

       EMFILE Osiągnięte  zostało  ograniczenie  liczby otwartych deskryptorów
              plików dla procesu.

       ENFILE Osiągnięte  zostało  systemowe  ograniczenie  liczby   otwartych
              deskryptorów plików.

       Funkcja accept może zakończyć się niepomyślnie gdy:

       EFAULT Parametr addr nie znajduje się w przestrzeni adresowej dostępnej
              do zapisu dla użytkownika.

       ENOBUFS, ENOMEM
              Jest niedostateczna ilość wolnej pamięci.  Oznacza to zazwyczaj,
              że  istnieje  ograniczenie  dla  przydzielania pamięci na bufory
              gniazd, nie zaś że zabrakło pamięci w systemie.

       EPROTO Wystąpił błąd protokołu.

       W Linuksie accept może również zakończyć się niepomyślnie gdy:

       EPERM  Reguły firewalla zabraniają połączenia.

       Dodatkowo,  dla  nowego  gniazda  mogą  być  zwracane  błędy   sieciowe
       zdefiniowane
              dla danego protokołu. Różne  jądra  Linuksa  mogą  zwracać  inne
              błędy,   takie   jak  ENOSR,  ESOCKTNOSUPPORT,  EPROTONOSUPPORT,
              ETIMEDOUT.  Wartość ERESTARTSYS  może  być  obserwowana  podczas
              śledzenia.

ZGODNE Z

       SVr4,  4.4BSD  (funkcja  accept  pojawiła  się  pierwotnie  w BSD 4.2).
       Strona podręcznika BSD opisuje pięć możliwych zwracanych błędów (EBADF,
       ENOTSOCK,   EOPNOTSUPP,  EWOULDBLOCK,  EFAULT).   SUSv3  opisuje  błędy
       EAGAIN, EBADF, ECONNABORTED, EINTR, EINVAL,  EMFILE,  ENFILE,  ENOBUFS,
       ENOMEM,  ENOTSOCK,  EOPNOTSUPP,  EPROTO,  EWOULDBLOCK.   SUSv2  opisuje
       dodatkowo błędy EFAULT i ENOSR.

       Linuksowe  accept  _nie_  dziedziczy  znaczników  gniazda,  takich  jak
       O_NONBLOCK.   Takie zachowanie różni się od innych implementacji gniazd
       BSD.  Przenośne programy nie  powinny  zakładać  takiego  zachowania  i
       zawsze ustawiać dla gniazda zwracanego przez accept wszystkie potrzebne
       znaczniki.

UWAGA

       Trzeci argument accept był pierwotnie zadeklarowany  jako  `int  *'  (i
       jest  pod  libc4 i libc5 oraz na wielu innych systemach, takich jak BSD
       4.*, SunOS 4, SGI); W szkicu standardu POSIX 1003.1g chciano to zmienić
       na `size_t *' i tak jest w SunOS 5.  Późniejsze szkice POSIX używają tu
       `socklen_t *' i tak samo robią  Single  Unix  Specification  i  glibc2.
       Cytując Linusa Torvaldsa: _Any_ sane library _must_ have "socklen_t" be
       the same size as int.  Anything else breaks any BSD socket layer stuff.
       POSIX  initially  _did_  make it a size_t, and I (and hopefully others,
       but obviously not too many) complained  to  them  very  loudly  indeed.
       Making  it  a  size_t is completely broken, exactly because size_t very
       seldom is the same size as "int" on 64-bit architectures, for  example.
       And  it  _has_ to be the same size as "int" because that's what the BSD
       socket interface is.  Anyway, the POSIX people eventually got  a  clue,
       and  created  "socklen_t".  They shouldn't have touched it in the first
       place, but once they did they felt it had to have a named type for some
       unfathomable  reason  (probably  somebody  didn't like losing face over
       having done the original stupid thing, so they  silently  just  renamed
       their blunder).

ZOBACZ TAKŻE

       bind(2), connect(2), listen(2), select(2), socket(2)