| 321 | */ |
| 322 | |
| 323 | int |
| 324 | lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) |
| 325 | { |
| 326 | struct lwip_sock *sock, *nsock; |
| 327 | struct netconn *newconn; |
| 328 | ip_addr_t naddr; |
| 329 | u16_t port; |
| 330 | int newsock; |
| 331 | struct sockaddr_in sin; |
| 332 | err_t err; |
| 333 | SYS_ARCH_DECL_PROTECT(lev); |
| 334 | |
| 335 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); |
| 336 | sock = get_socket(s); |
| 337 | if (!sock) { |
| 338 | return -1; |
| 339 | } |
| 340 | |
| 341 | if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { |
| 342 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); |
| 343 | sock_set_errno(sock, EWOULDBLOCK); |
| 344 | return -1; |
| 345 | } |
| 346 | |
| 347 | /* wait for a new connection */ |
| 348 | err = netconn_accept(sock->conn, &newconn); |
| 349 | if (err != ERR_OK) { |
| 350 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); |
| 351 | if (netconn_type(sock->conn) != NETCONN_TCP) { |
| 352 | sock_set_errno(sock, EOPNOTSUPP); |
| 353 | return EOPNOTSUPP; |
| 354 | } |
| 355 | sock_set_errno(sock, err_to_errno(err)); |
| 356 | return -1; |
| 357 | } |
| 358 | LWIP_ASSERT("newconn != NULL", newconn != NULL); |
| 359 | /* Prevent automatic window updates, we do this on our own! */ |
| 360 | netconn_set_noautorecved(newconn, 1); |
| 361 | |
| 362 | /* get the IP address and port of the remote host */ |
| 363 | err = netconn_peer(newconn, &naddr, &port); |
| 364 | if (err != ERR_OK) { |
| 365 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); |
| 366 | netconn_delete(newconn); |
| 367 | sock_set_errno(sock, err_to_errno(err)); |
| 368 | return -1; |
| 369 | } |
| 370 | |
| 371 | /* Note that POSIX only requires us to check addr is non-NULL. addrlen must |
| 372 | * not be NULL if addr is valid. |
| 373 | */ |
| 374 | if (NULL != addr) { |
| 375 | LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); |
| 376 | memset(&sin, 0, sizeof(sin)); |
| 377 | sin.sin_len = sizeof(sin); |
| 378 | sin.sin_family = AF_INET; |
| 379 | sin.sin_port = htons(port); |
| 380 | inet_addr_from_ipaddr(&sin.sin_addr, &naddr); |
nothing calls this directly
no test coverage detected