tcp_listen.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /* include tcp_listen */
  2. #include "unp.h"
  3. int
  4. tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
  5. {
  6. int listenfd, n;
  7. const int on = 1;
  8. struct addrinfo hints, *res, *ressave;
  9. bzero(&hints, sizeof(struct addrinfo));
  10. hints.ai_flags = AI_PASSIVE;
  11. hints.ai_family = AF_UNSPEC;
  12. hints.ai_socktype = SOCK_STREAM;
  13. if ( (n = getaddrinfo(host, serv, &hints, &res)) != 0)
  14. err_quit("tcp_listen error for %s, %s: %s",
  15. host, serv, gai_strerror(n));
  16. ressave = res;
  17. do {
  18. listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
  19. if (listenfd < 0)
  20. continue; /* error, try next one */
  21. Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
  22. if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
  23. break; /* success */
  24. Close(listenfd); /* bind error, close and try next one */
  25. } while ( (res = res->ai_next) != NULL);
  26. if (res == NULL) /* errno from final socket() or bind() */
  27. err_sys("tcp_listen error for %s, %s", host, serv);
  28. Listen(listenfd, LISTENQ);
  29. if (addrlenp)
  30. *addrlenp = res->ai_addrlen; /* return size of protocol address */
  31. freeaddrinfo(ressave);
  32. return(listenfd);
  33. }
  34. /* end tcp_listen */
  35. /*
  36. * We place the wrapper function here, not in wraplib.c, because some
  37. * XTI programs need to include wraplib.c, and it also defines
  38. * a Tcp_listen() function.
  39. */
  40. int
  41. Tcp_listen(const char *host, const char *serv, socklen_t *addrlenp)
  42. {
  43. return(tcp_listen(host, serv, addrlenp));
  44. }