Fixed, close() forgottens fds after fork

+ minors changes
+ Super new epoll loop output :)
This commit is contained in:
lperrey
2022-08-17 01:49:31 +02:00
parent ccc542f52b
commit 9f3903d497
4 changed files with 65 additions and 25 deletions

View File

@@ -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 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 0x427962: Webserv::run() (run_loop.cpp:153)
==847174== by 0x4052E9: main (main.cpp:38) ==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()

View File

@@ -107,6 +107,7 @@ class Webserv
void _close_client(int fd); void _close_client(int fd);
void _close_all_clients(); void _close_all_clients();
void _close_all_clients_fd(); void _close_all_clients_fd();
void _close_all_clients_cgi_fd();
void _close_cgi_pipe_rfd(int fd); void _close_cgi_pipe_rfd(int fd);
void _close_all_cgi_pipe_rfd(); void _close_all_cgi_pipe_rfd();
void _close_all_listen_sockets(); void _close_all_listen_sockets();

View File

@@ -28,6 +28,7 @@ void Webserv::_close_all_clients()
void Webserv::_close_all_clients_fd() void Webserv::_close_all_clients_fd()
{ {
_close_all_clients_cgi_fd();
std::vector<Client>::iterator it = _clients.begin(); std::vector<Client>::iterator it = _clients.begin();
std::vector<Client>::iterator it_end = _clients.end(); std::vector<Client>::iterator it_end = _clients.end();
while (it != it_end) while (it != it_end)
@@ -40,6 +41,24 @@ void Webserv::_close_all_clients_fd()
} }
} }
void Webserv::_close_all_clients_cgi_fd()
{
std::vector<Client>::iterator it = _clients.begin();
std::vector<Client>::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() void Webserv::_close_all_listen_sockets()
{ // TODO : change like clients (clear in place of pop_back) { // TODO : change like clients (clear in place of pop_back)
while (!_listen_sockets.empty()) 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 std::cerr << "EPOLLERR on client fd " << fd << "\n"; // DEBUG
if (events & EPOLLHUP) if (events & EPOLLHUP)
std::cerr << "EPOLLHUP on client fd " << fd << "\n"; // DEBUG 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.
} }

View File

@@ -11,7 +11,6 @@ void Webserv::_read_cgi_output(Client *client)
{ {
char buf[BUFSIZE]; char buf[BUFSIZE];
ssize_t ret; ssize_t ret;
pid_t wait_ret;
std::cerr << "_read_cgi_output()" << "\n"; std::cerr << "_read_cgi_output()" << "\n";
std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\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 << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\n"; std::cerr << "client fd = " << client->get_cl_fd() << "\n";
std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\n"; std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\n";
client->cgi_output = STATUS_500;
pid_t wait_ret; pid_t wait_ret;
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG); wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG);
std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n"; std::cerr << "cgi EPOLLERR waitpid ret = " << wait_ret << "\n";
if (wait_ret == 0) 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); _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) 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)events;
(void)client; (void)client;
std::cerr << "cgi EPOLLHUP" << "\n"; /* std::cerr << "cgi EPOLLHUP" << "\n";
std::cerr << "cgi_pid = " << client->cgi_pid << "\n"; std::cerr << "cgi_pid = " << client->cgi_pid << "\n";
std::cerr << "client fd = " << client->get_cl_fd() << "\n"; std::cerr << "client fd = " << client->get_cl_fd() << "\n";
std::cerr << "cgi fd = " << client->cgi_pipe_rfd << "\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;
pid_t wait_ret; pid_t wait_ret;
wait_ret = ::waitpid(client->cgi_pid, NULL, WNOHANG); 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 (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); _epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
} }
} }
@@ -107,8 +106,9 @@ void Webserv::run()
g_run = true; g_run = true;
while (g_run) while (g_run)
{ {
std::cerr << ++count_loop << "----loop epoll()\n"; std::cerr << ++count_loop << "----loop epoll() ";
nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT); nfds = ::epoll_wait(_epfd, events, MAX_EVENTS, TIMEOUT);
std::cerr << "(nfds=" << nfds << ")\n";
if (nfds == -1) if (nfds == -1)
{ {
int errno_copy = errno; int errno_copy = errno;
@@ -142,7 +142,7 @@ void Webserv::run()
else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) ) else if ( (events[i].events & EPOLLHUP) && !(events[i].events & EPOLLIN) )
_cgi_epollhup(events[i].events, client_cgi); _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) if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
_handle_epoll_error_client(events[i].events, events[i].data.fd); _handle_epoll_error_client(events[i].events, events[i].data.fd);