WIP CGI monitered by epoll
+ OK, but some errors case need to be lookup
This commit is contained in:
@@ -4,6 +4,96 @@
|
||||
#define MAX_EVENTS 42 // arbitrary
|
||||
#define TIMEOUT 3000
|
||||
|
||||
// TODO: temp to move in own file
|
||||
bool operator==(const cgi_pipe_rfd& lhs, int fd)
|
||||
{ return lhs.fd == fd; }
|
||||
|
||||
bool operator==(int fd, const cgi_pipe_rfd& rhs)
|
||||
{ return fd == rhs.fd; }
|
||||
|
||||
#define BUFSIZE 8192 // (8Ko)
|
||||
#define STATUS_500 std::string("Status: 500" CRLF CRLF);
|
||||
void Webserv::_read_cgi_output(cgi_pipe_rfd &cgi_fd)
|
||||
{
|
||||
char buf[BUFSIZE];
|
||||
ssize_t ret;
|
||||
pid_t wait_ret;
|
||||
|
||||
ret = ::read(cgi_fd.fd, buf, BUFSIZE);
|
||||
std::cerr << "cgi read ret = " << ret << "\n";
|
||||
if (ret == -1)
|
||||
{
|
||||
std::perror("err read(cgi_fd)");
|
||||
cgi_fd.client->cgi_output = STATUS_500;
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
(void)0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cgi_fd.client->cgi_output.append(buf, ret);
|
||||
}
|
||||
|
||||
|
||||
wait_ret = ::waitpid(cgi_fd.cgi_pid, NULL, WNOHANG);
|
||||
std::cerr << "cgi waitpid ret = " << wait_ret << "\n";
|
||||
if (wait_ret == 0 && ret == -1)
|
||||
{
|
||||
_epoll_update(cgi_fd.client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(cgi_fd.fd);
|
||||
// TODO: kill the child :)
|
||||
}
|
||||
else if (wait_ret == cgi_fd.cgi_pid)
|
||||
{
|
||||
_epoll_update(cgi_fd.client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(cgi_fd.fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Webserv::_handle_epoll_error_cgi_fd(uint32_t events, std::vector<cgi_pipe_rfd>::iterator it)
|
||||
{
|
||||
(void)events;
|
||||
std::cerr << "cgi EPOLLERR" << "\n";
|
||||
|
||||
pid_t wait_ret;
|
||||
wait_ret = ::waitpid(it->cgi_pid, NULL, WNOHANG);
|
||||
std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
|
||||
if (wait_ret == 0)
|
||||
{
|
||||
_epoll_update(it->client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(it->fd);
|
||||
// TODO: kill the child :)
|
||||
}
|
||||
else if (wait_ret == it->cgi_pid)
|
||||
{
|
||||
_epoll_update(it->client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(it->fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Webserv::_cgi_epollhup(uint32_t events, std::vector<cgi_pipe_rfd>::iterator it)
|
||||
{
|
||||
(void)events;
|
||||
std::cerr << "cgi EPOLLHUP" << "\n";
|
||||
|
||||
pid_t wait_ret;
|
||||
wait_ret = ::waitpid(it->cgi_pid, NULL, WNOHANG);
|
||||
std::cerr << "cgi EPOLLHUP waitpid ret = " << wait_ret << "\n";
|
||||
if (wait_ret == 0)
|
||||
{
|
||||
_epoll_update(it->client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(it->fd);
|
||||
// TODO: kill the child :)
|
||||
}
|
||||
else if (wait_ret == it->cgi_pid)
|
||||
{
|
||||
_epoll_update(it->client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_ADD);
|
||||
_close_cgi_pipe_rfd(it->fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Webserv::run()
|
||||
{
|
||||
std::cerr << "Server started\n";
|
||||
@@ -11,7 +101,8 @@ void Webserv::run()
|
||||
int nfds;
|
||||
int i;
|
||||
int count_loop = 0;
|
||||
std::vector<listen_socket>::iterator it_socket;
|
||||
std::vector<listen_socket>::iterator it_lsocket;
|
||||
std::vector<cgi_pipe_rfd>::iterator it_cgi_fd;
|
||||
|
||||
g_run = true;
|
||||
while (g_run)
|
||||
@@ -33,13 +124,23 @@ void Webserv::run()
|
||||
while (i < nfds)
|
||||
{
|
||||
try {
|
||||
it_socket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||
if (it_socket != _listen_sockets.end())
|
||||
it_lsocket = std::find(_listen_sockets.begin(), _listen_sockets.end(), events[i].data.fd);
|
||||
it_cgi_fd = std::find(_cgi_pipe_rfds.begin(), _cgi_pipe_rfds.end(), events[i].data.fd); // Could be moved in the loop to avoid useless find() call
|
||||
if (it_lsocket != _listen_sockets.end())
|
||||
{
|
||||
if (events[i].events & EPOLLERR || events[i].events & EPOLLHUP)
|
||||
_handle_epoll_error_lsocket(events[i].events, it_socket);
|
||||
_handle_epoll_error_lsocket(events[i].events, it_lsocket);
|
||||
else if (events[i].events & EPOLLIN)
|
||||
_accept_connection(*it_socket);
|
||||
_accept_connection(*it_lsocket);
|
||||
}
|
||||
else if (it_cgi_fd != _cgi_pipe_rfds.end())
|
||||
{
|
||||
if (events[i].events & EPOLLERR)
|
||||
_handle_epoll_error_cgi_fd(events[i].events, it_cgi_fd);
|
||||
else if (events[i].events & EPOLLHUP)
|
||||
_cgi_epollhup(events[i].events, it_cgi_fd);
|
||||
else if (events[i].events & EPOLLIN)
|
||||
_read_cgi_output(*it_cgi_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user