Files
42_INT_12_webserv/srcs/webserv/close.cpp
lperrey f8c6923c6d fixed CGI alloc
+ handle unknow status from script
2022-08-16 01:46:24 +02:00

113 lines
2.8 KiB
C++

#include "Webserv.hpp"
void Webserv::_close_client(int fd)
{
std::vector<Client>::iterator it = _clients.begin();
while (it != _clients.end())
{
if (*it == fd)
{
// _epoll_update(fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
std::cerr << "close fd " << fd << "\n";
if (::close(fd) == -1)
std::perror("err close()");
_clients.erase(it);
break;
}
++it;
}
}
void Webserv::_close_all_clients()
{
while (!_clients.empty())
{
// _epoll_update(_clients.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
std::cerr << "close fd " << _clients.back().get_cl_fd() << "\n";
if (::close(_clients.back().get_cl_fd()) == -1)
std::perror("err close()");
_clients.pop_back();
}
}
void Webserv::_close_all_listen_sockets()
{
while (!_listen_sockets.empty())
{
// _epoll_update(_listen_sockets.back().fd, 0, EPOLL_CTL_DEL); // normalement superflu, DEBUG
std::cerr << "close fd " << _listen_sockets.back().fd << "\n";
if (::close(_listen_sockets.back().fd) == -1)
std::perror("err close()");
_listen_sockets.pop_back();
}
}
void Webserv::_reopen_lsocket(std::vector<listen_socket>::iterator it)
{
/*
** Many common code with init_virtual_servers(). Could refactor it.
*/
int ret;
std::cerr << "close lsocket " << it->fd << "\n";
if (::close(it->fd) == -1)
std::perror("err close()");
std::cerr << "try to reopen lsocket\n";
ret = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (ret == -1)
{
std::perror("err socket()");
_listen_sockets.erase(it);
return;
}
it->fd = ret;
// HUGO ADD
// allow socket descriptor to be reuseable
// I just copied it from https://www.ibm.com/docs/en/i/7.2?topic=designs-example-nonblocking-io-select
int on = 1;
if (setsockopt(it->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
{
::perror("err setsockopt()");
_listen_sockets.erase(it);
return;
}
// HUGO ADD END
try {
_bind(it->fd, std::strtoul(it->port.c_str(), NULL, 10), it->host);
_listen(it->fd, 42); // 42 arbitrary
}
catch (const std::exception& e) {
std::cerr << e.what() << '\n';
_listen_sockets.erase(it);
return;
}
if (_epoll_update(it->fd, EPOLLIN, EPOLL_CTL_ADD) == -1)
{
_listen_sockets.erase(it);
return;
}
std::cerr << "reopen success\n";
}
void Webserv::_handle_epoll_error_lsocket(uint32_t events, std::vector<listen_socket>::iterator it)
{
if (events & EPOLLERR)
std::cerr << "EPOLLERR on lsocket fd " << it->fd << "\n"; // DEBUG
if (events & EPOLLHUP)
std::cerr << "EPOLLHUP on lsocket fd " << it->fd << "\n"; // DEBUG
_reopen_lsocket(it);
}
void Webserv::_handle_epoll_error_client(uint32_t events, int fd)
{
if (events & EPOLLERR)
std::cerr << "EPOLLERR on client fd " << fd << "\n"; // DEBUG
if (events & EPOLLHUP)
std::cerr << "EPOLLHUP on client fd " << fd << "\n"; // DEBUG
_close_client(fd);
}