From 9f3903d4970de003e6c13f5636198a9420cb012a Mon Sep 17 00:00:00 2001 From: lperrey Date: Wed, 17 Aug 2022 01:49:31 +0200 Subject: [PATCH] Fixed, close() forgottens fds after fork + minors changes + Super new epoll loop output :) --- memo.txt | 17 ++++++++++++++ srcs/webserv/Webserv.hpp | 1 + srcs/webserv/close.cpp | 24 +++++++++++++++++++- srcs/webserv/run_loop.cpp | 48 +++++++++++++++++++-------------------- 4 files changed, 65 insertions(+), 25 deletions(-) diff --git a/memo.txt b/memo.txt index dd8e42a..d86090a 100644 --- a/memo.txt +++ b/memo.txt @@ -59,3 +59,20 @@ Valgrind error RESOLVED ! : ==847174== by 0x426BC5: Webserv::_read_cgi_output(cgi_pipe_rfd&) (run_loop.cpp:39) // (LUKE: its an string.append() call) ==847174== by 0x427962: Webserv::run() (run_loop.cpp:153) ==847174== by 0x4052E9: main (main.cpp:38) + +RESOLVED, AGAIN :D ! +--loop epoll() +EPOLLHUP on client fd 8 +47067----loop epoll() +EPOLLHUP on client fd 8 +47068----loop epoll() +EPOLLHUP on client fd 8 +47069----loop epoll() +EPOLLHUP on client fd 8 +47070----loop epoll() +EPOLLHUP on client fd 8 +47071----loop epoll() +EPOLLHUP on client fd 8 +47072----loop epoll() +EPOLLHUP on client fd 8 +47073----loop epoll() diff --git a/srcs/webserv/Webserv.hpp b/srcs/webserv/Webserv.hpp index 1b8ce8e..d7ecf42 100644 --- a/srcs/webserv/Webserv.hpp +++ b/srcs/webserv/Webserv.hpp @@ -107,6 +107,7 @@ class Webserv void _close_client(int fd); void _close_all_clients(); void _close_all_clients_fd(); + void _close_all_clients_cgi_fd(); void _close_cgi_pipe_rfd(int fd); void _close_all_cgi_pipe_rfd(); void _close_all_listen_sockets(); diff --git a/srcs/webserv/close.cpp b/srcs/webserv/close.cpp index 145287c..138be7e 100644 --- a/srcs/webserv/close.cpp +++ b/srcs/webserv/close.cpp @@ -28,6 +28,7 @@ void Webserv::_close_all_clients() void Webserv::_close_all_clients_fd() { + _close_all_clients_cgi_fd(); std::vector::iterator it = _clients.begin(); std::vector::iterator it_end = _clients.end(); while (it != it_end) @@ -40,6 +41,24 @@ void Webserv::_close_all_clients_fd() } } +void Webserv::_close_all_clients_cgi_fd() +{ + std::vector::iterator it = _clients.begin(); + std::vector::iterator it_end = _clients.end(); + while (it != it_end) + { + // _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG + if (it->cgi_pipe_rfd) + { + std::cerr << "close cgi-fd " << it->cgi_pipe_rfd << "\n"; + if (::close(it->cgi_pipe_rfd) == -1) + std::perror("err close()"); + } + ++it; + } +} + + void Webserv::_close_all_listen_sockets() { // TODO : change like clients (clear in place of pop_back) while (!_listen_sockets.empty()) @@ -117,5 +136,8 @@ void Webserv::_handle_epoll_error_client(uint32_t events, int fd) std::cerr << "EPOLLERR on client fd " << fd << "\n"; // DEBUG if (events & EPOLLHUP) std::cerr << "EPOLLHUP on client fd " << fd << "\n"; // DEBUG - _close_client(fd); + if (std::find(_clients.begin(), _clients.end(), fd) != _clients.end()) + std::cerr << "Found the client in _clients" << "\n"; // DEBUG + + _close_client(fd); // " EPOLLHUP on client fd 8 " en boucle quand on mattraque un peu les CGI, donc il ne le trouve pas dans _clients. Etrange. } diff --git a/srcs/webserv/run_loop.cpp b/srcs/webserv/run_loop.cpp index 6301c6e..1b1e644 100644 --- a/srcs/webserv/run_loop.cpp +++ b/srcs/webserv/run_loop.cpp @@ -11,7 +11,6 @@ void Webserv::_read_cgi_output(Client *client) { char buf[BUFSIZE]; ssize_t ret; - pid_t wait_ret; std::cerr << "_read_cgi_output()" << "\n"; std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; std::cerr << "client fd = " << client->get_cl_fd() << "\n"; @@ -37,23 +36,23 @@ void Webserv::_handle_epoll_error_cgi_fd(uint32_t events, Client *client) std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; std::cerr << "client fd = " << client->get_cl_fd() << "\n"; std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\n"; - + + client->cgi_output = STATUS_500; + pid_t wait_ret; wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG); - std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n"; - if (wait_ret == 0) + std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n"; + if (wait_ret == client->cgi_pid) { + if (client->cgi_pipe_rfd) + { + if (::close(client->cgi_pipe_rfd) == -1) + std::perror("err close()"); + } + client->cgi_pipe_rfd = 0; _epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD); - if (::close(client->cgi_pipe_rfd) == -1) - std::perror("err close()"); - // TODO: kill the child :) } - else if (wait_ret == client->cgi_pid) - { - _epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD); - if (::close(client->cgi_pipe_rfd) == -1) - std::perror("err close()"); - } + } void Webserv::_cgi_epollhup(uint32_t events, Client *client) @@ -61,22 +60,22 @@ void Webserv::_cgi_epollhup(uint32_t events, Client *client) (void)events; (void)client; - std::cerr << "cgi EPOLLHUP" << "\n"; +/* std::cerr << "cgi EPOLLHUP" << "\n"; std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; std::cerr << "client fd = " << client->get_cl_fd() << "\n"; - std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\n"; - if (client->cgi_pipe_rfd) - { - if (::close(client->cgi_pipe_rfd) == -1) - std::perror("err close()"); - } - client->cgi_pipe_rfd = 0; + std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\n"; */ pid_t wait_ret; wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG); - std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n"; + // std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n"; if (wait_ret == client->cgi_pid) { + if (client->cgi_pipe_rfd) + { + if (::close(client->cgi_pipe_rfd) == -1) + std::perror("err close()"); + } + client->cgi_pipe_rfd = 0; _epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD); } } @@ -107,8 +106,9 @@ void Webserv::run() g_run = true; while (g_run) { - std::cerr << ++count_loop << "----loop epoll()\n"; + std::cerr << ++count_loop << "----loop epoll() "; nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT); + std::cerr << "(nfds=" << nfds << ")\n"; if (nfds == -1) { int errno_copy = errno; @@ -142,7 +142,7 @@ void Webserv::run() else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) ) _cgi_epollhup(events[i].events, client_cgi); } - else + else if (std::find(_clients.begin(), _clients.end(), events[i].data.fd) != _clients.end()) // TODO: save the it in var to avoid multiples find() { if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP) _handle_epoll_error_client(events[i].events, events[i].data.fd);