int make_socket_fd(int log_level, const char* address, int flags) { SocketAddress a; int fd, r; r = socket_address_parse(&a, address); if (r < 0) { log_error("Failed to parse socket address \"%s\": %s", address, strerror(-r)); return r; } fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, NULL, false, false, 0755, 0644, NULL); if (fd < 0 || log_get_max_level() >= log_level) { _cleanup_free_ char *p = NULL; r = socket_address_print(&a, &p); if (r < 0) return log_error_errno(r, "socket_address_print(): %m"); if (fd < 0) log_error_errno(fd, "Failed to listen on %s: %m", p); else log_full(log_level, "Listening on %s", p); } return fd; }
static int print_socket(const char* desc, int fd) { int r; SocketAddress addr = { .size = sizeof(union sockaddr_union), .type = SOCK_STREAM, }; int family; r = getsockname(fd, &addr.sockaddr.sa, &addr.size); if (r < 0) { log_warning("Failed to query socket on fd:%d: %m", fd); return 0; } family = socket_address_family(&addr); switch(family) { case AF_INET: case AF_INET6: { char* _cleanup_free_ a = NULL; r = socket_address_print(&addr, &a); if (r < 0) log_warning("socket_address_print(): %s", strerror(-r)); else log_info("%s %s address %s", desc, family == AF_INET ? "IP" : "IPv6", a); break; } default: log_warning("Connection with unknown family %d", family); } return 0; } static int open_sockets(int *epoll_fd, bool accept) { int n, fd; int count = 0; char **address; n = sd_listen_fds(true); if (n < 0) { log_error("Failed to read listening file descriptors from environment: %s", strerror(-n)); return n; } log_info("Received %d descriptors", n); for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) { log_debug("Received descriptor fd:%d", fd); print_socket("Listening on", fd); if (!arg_accept) { int r = set_nocloexec(fd); if (r < 0) return r; } count ++; } /** Note: we leak some fd's on error here. I doesn't matter * much, since the program will exit immediately anyway, but * would be a pain to fix. */ STRV_FOREACH(address, arg_listen) { log_info("Opening address %s", *address); fd = make_socket_fd(*address, SOCK_STREAM | (arg_accept*SOCK_CLOEXEC)); if (fd < 0) { log_error("Failed to open '%s': %s", *address, strerror(-fd)); return fd; } count ++; }