END_TEST START_TEST (inet_listen_test) { int fd, mode, sockfd = -1, port = INPORT_ANY, res; conn_t *conn; res = pr_inet_listen(NULL, NULL, 5, 0); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); res = pr_inet_resetlisten(NULL, NULL); fail_unless(res < 0, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE); fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno)); fd = conn->listen_fd; conn->listen_fd = 777; res = pr_inet_listen(p, conn, 5, 0); fail_unless(res < 0, "Succeeded in listening on conn unexpectedly"); fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF, strerror(errno), errno); mode = conn->mode; res = pr_inet_resetlisten(p, conn); fail_unless(res < 0, "Succeeded in resetting listening on conn unexpectedly"); fail_unless(errno == EBADF, "Expected EBADF (%d), got %s (%d)", EBADF, strerror(errno), errno); conn->listen_fd = fd; conn->mode = mode; res = pr_inet_listen(p, conn, 5, 0); fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno)); res = pr_inet_resetlisten(p, conn); fail_unless(res == 0, "Failed to reset listen mode: %s", strerror(errno)); res = pr_inet_listen(p, conn, 5, 0); fail_unless(res < 0, "Failed to handle already-listening socket"); fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM, strerror(errno), errno); pr_inet_close(p, conn); }
int pr_ipbind_listen(fd_set *readfds) { int listen_flags = PR_INET_LISTEN_FL_FATAL_ON_ERROR, maxfd = 0; register unsigned int i = 0; /* sanity check */ if (!readfds) return -1; FD_ZERO(readfds); if (!binding_pool) { binding_pool = make_sub_pool(permanent_pool); pr_pool_tag(binding_pool, "Bindings Pool"); } /* Reset the listener list. */ if (!listener_list) { listener_list = make_array(binding_pool, 1, sizeof(conn_t *)); } else { /* Nasty hack to "clear" the list by making it think it has no * elements. */ listener_list->nelts = 0; } /* Slower than the hash lookup, but...we have to check each and every * ipbind in the table. */ for (i = 0; i < PR_BINDINGS_TABLE_SIZE; i++) { pr_ipbind_t *ipbind = NULL; for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) { /* Skip inactive bindings, but only if SocketBindTight is in effect. */ if (SocketBindTight && !ipbind->ib_isactive) continue; if (ipbind->ib_listener) { if (ipbind->ib_listener->mode == CM_NONE) { pr_inet_listen(ipbind->ib_listener->pool, ipbind->ib_listener, tcpBackLog, listen_flags); } if (ipbind->ib_listener->mode == CM_ACCEPT) { if (pr_inet_resetlisten(ipbind->ib_listener->pool, ipbind->ib_listener) < 0) { pr_trace_msg(trace_channel, 3, "error resetting %s#%u for listening: %s", pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port, strerror(errno)); } } if (ipbind->ib_listener->mode == CM_LISTEN) { FD_SET(ipbind->ib_listener->listen_fd, readfds); if (ipbind->ib_listener->listen_fd > maxfd) maxfd = ipbind->ib_listener->listen_fd; /* Add this to the listener list as well. */ *((conn_t **) push_array(listener_list)) = ipbind->ib_listener; } } } } return maxfd; }