/* Thread: main */ void httpd_deinit(void) { int ret; #ifdef USE_EVENTFD ret = eventfd_write(exit_efd, 1); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not send exit event: %s\n", strerror(errno)); return; } #else int dummy = 42; ret = write(exit_pipe[1], &dummy, sizeof(dummy)); if (ret != sizeof(dummy)) { DPRINTF(E_FATAL, L_HTTPD, "Could not write to exit fd: %s\n", strerror(errno)); return; } #endif ret = pthread_join(tid_httpd, NULL); if (ret != 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not join HTTPd thread: %s\n", strerror(errno)); return; } streaming_deinit(); rsp_deinit(); dacp_deinit(); daap_deinit(); #ifdef USE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); close(exit_pipe[1]); #endif evhttp_free(evhttpd); event_base_free(evbase_httpd); }
/* Thread: main */ int httpd_init(void) { unsigned short port; int v6enabled; int ret; httpd_exit = 0; v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6"); evbase_httpd = event_base_new(); if (!evbase_httpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create an event base\n"); return -1; } ret = rsp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "RSP protocol init failed\n"); goto rsp_fail; } ret = daap_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DAAP protocol init failed\n"); goto daap_fail; } ret = dacp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DACP protocol init failed\n"); goto dacp_fail; } #ifdef USE_EVENTFD exit_efd = eventfd(0, EFD_CLOEXEC); if (exit_efd < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create eventfd: %s\n", strerror(errno)); goto pipe_fail; } #else # if defined(__linux__) ret = pipe2(exit_pipe, O_CLOEXEC); # else ret = pipe(exit_pipe); # endif if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create pipe: %s\n", strerror(errno)); goto pipe_fail; } #endif /* USE_EVENTFD */ #ifdef USE_EVENTFD event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL); #else event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL); #endif event_base_set(evbase_httpd, &exitev); event_add(&exitev, NULL); evhttpd = evhttp_new(evbase_httpd); if (!evhttpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create HTTP server\n"); goto evhttp_fail; } port = cfg_getint(cfg_getsec(cfg, "library"), "port"); /* We are binding v6 and v4 separately, and we allow v6 to fail * as IPv6 might not be supported on the system. * We still warn about the failure, in case there's another issue. */ ret = evhttp_bind_socket(evhttpd, "0.0.0.0", port); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not bind INADDR_ANY:%d\n", port); goto bind_fail; } if (v6enabled) { ret = evhttp_bind_socket(evhttpd, "::", port); if (ret < 0) DPRINTF(E_WARN, L_HTTPD, "Could not bind IN6ADDR_ANY:%d (that's OK)\n", port); } evhttp_set_gencb(evhttpd, httpd_gen_cb, NULL); ret = pthread_create(&tid_httpd, NULL, httpd, NULL); if (ret != 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not spawn HTTPd thread: %s\n", strerror(errno)); goto thread_fail; } return 0; thread_fail: bind_fail: evhttp_free(evhttpd); evhttp_fail: #ifdef USE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); close(exit_pipe[1]); #endif pipe_fail: dacp_deinit(); dacp_fail: daap_deinit(); daap_fail: rsp_deinit(); rsp_fail: event_base_free(evbase_httpd); return -1; }
/* Thread: main */ int httpd_init(void) { int v6enabled; unsigned short port; int ret; httpd_exit = 0; evbase_httpd = event_base_new(); if (!evbase_httpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create an event base\n"); return -1; } ret = rsp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "RSP protocol init failed\n"); goto rsp_fail; } ret = daap_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DAAP protocol init failed\n"); goto daap_fail; } ret = dacp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DACP protocol init failed\n"); goto dacp_fail; } streaming_init(); #ifdef USE_EVENTFD exit_efd = eventfd(0, EFD_CLOEXEC); if (exit_efd < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create eventfd: %s\n", strerror(errno)); goto pipe_fail; } exitev = event_new(evbase_httpd, exit_efd, EV_READ, exit_cb, NULL); #else ret = pipe2(exit_pipe, O_CLOEXEC); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create pipe: %s\n", strerror(errno)); goto pipe_fail; } exitev = event_new(evbase_httpd, exit_pipe[0], EV_READ, exit_cb, NULL); #endif /* USE_EVENTFD */ if (!exitev) { DPRINTF(E_FATAL, L_HTTPD, "Could not create exit event\n"); goto event_fail; } event_add(exitev, NULL); evhttpd = evhttp_new(evbase_httpd); if (!evhttpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create HTTP server\n"); goto event_fail; } v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6"); port = cfg_getint(cfg_getsec(cfg, "library"), "port"); if (v6enabled) { ret = evhttp_bind_socket(evhttpd, "::", port); if (ret < 0) { DPRINTF(E_LOG, L_HTTPD, "Could not bind to port %d, falling back to IPv4\n", port); v6enabled = 0; } } if (!v6enabled) { ret = evhttp_bind_socket(evhttpd, "0.0.0.0", port); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not bind to port %d (forked-daapd already running?)\n", port); goto bind_fail; } } evhttp_set_gencb(evhttpd, httpd_gen_cb, NULL); ret = pthread_create(&tid_httpd, NULL, httpd, NULL); if (ret != 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not spawn HTTPd thread: %s\n", strerror(errno)); goto thread_fail; } return 0; thread_fail: bind_fail: evhttp_free(evhttpd); event_fail: #ifdef USE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); close(exit_pipe[1]); #endif pipe_fail: streaming_deinit(); dacp_deinit(); dacp_fail: daap_deinit(); daap_fail: rsp_deinit(); rsp_fail: event_base_free(evbase_httpd); return -1; }
/* Thread: main */ int httpd_init(void) { const char *addr; unsigned short port; int ret; httpd_exit = 0; evbase_httpd = event_base_new(); if (!evbase_httpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create an event base\n"); return -1; } ret = rsp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "RSP protocol init failed\n"); goto rsp_fail; } ret = daap_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DAAP protocol init failed\n"); goto daap_fail; } ret = dacp_init(); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "DACP protocol init failed\n"); goto dacp_fail; } #ifdef USE_EVENTFD exit_efd = eventfd(0, EFD_CLOEXEC); if (exit_efd < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create eventfd: %s\n", strerror(errno)); goto pipe_fail; } #else # if defined(__linux__) ret = pipe2(exit_pipe, O_CLOEXEC); # else ret = pipe(exit_pipe); # endif if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not create pipe: %s\n", strerror(errno)); goto pipe_fail; } #endif /* USE_EVENTFD */ #ifdef USE_EVENTFD event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL); #else event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL); #endif event_base_set(evbase_httpd, &exitev); event_add(&exitev, NULL); evhttpd = evhttp_new(evbase_httpd); if (!evhttpd) { DPRINTF(E_FATAL, L_HTTPD, "Could not create HTTP server\n"); goto evhttp_fail; } if (cfg_getbool(cfg_getsec(cfg, "general"), "ipv6")) addr = "::"; else addr = "0.0.0.0"; port = cfg_getint(cfg_getsec(cfg, "library"), "port"); ret = evhttp_bind_socket(evhttpd, addr, port); if (ret < 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not bind %s:%d\n", addr, port); goto bind_fail; } evhttp_set_gencb(evhttpd, httpd_gen_cb, NULL); ret = pthread_create(&tid_httpd, NULL, httpd, NULL); if (ret != 0) { DPRINTF(E_FATAL, L_HTTPD, "Could not spawn HTTPd thread: %s\n", strerror(errno)); goto thread_fail; } return 0; thread_fail: bind_fail: evhttp_free(evhttpd); evhttp_fail: #ifdef USE_EVENTFD close(exit_efd); #else close(exit_pipe[0]); close(exit_pipe[1]); #endif pipe_fail: dacp_deinit(); dacp_fail: daap_deinit(); daap_fail: rsp_deinit(); rsp_fail: event_base_free(evbase_httpd); return -1; }