#include <common.h> #include <FCGI/SocketHandler.h> #include <FCGI/RecordReader.h> #include <sys/epoll.h> #define ON_ERRNO() recordError(__LINE__,errno) #define ON_ERROR(S) recordError(__LINE__,(S)) static void recordError(int iLine,int iError) { TRACE_PRINT(("*" __FILE__ "(%d) - ERROR(%d) %s",iLine,iError,::strerror(iError))); } static void recordError(int iLine,const char* sError) { TRACE_PRINT(("*" __FILE__ "(%d) - ERROR %s",iLine,sError)); } struct FCGI::AcceptHandler: FCGI::SocketHandler { SOCKET socket; int hPoll; virtual void onRead(); }; struct FCGI::ConnectionHandler: FCGI::SocketHandler { SOCKET socket; FCGI::RecordReader reader; virtual void onRead(); virtual void onWrite(); }; static bool makeNonBlocking(SOCKET socket) { int v = fcntl(socket,F_GETFL,0); return (0 <= v) && (0 <= fcntl(socket,F_SETFL,v | O_NONBLOCK)); } void FCGI::AcceptHandler::onRead() { TRACE_FN(AcceptHandler::onRead); struct sockaddr_storage addressClient; socklen_t lengthAddress = sizeof(addressClient); SOCKET socketClient = ::accept(socket,(struct sockaddr*) &addressClient,&lengthAddress); if (socketClient < 0) { if ((EWOULDBLOCK == errno) || (EAGAIN == errno)) { return; // ignore } ON_ERRNO(); return; } //TRACE_PRINT(("*CONNECTION from ",addressClient.)) if (!makeNonBlocking(socketClient)) { ON_ERRNO(); return; } struct epoll_event ev; ev.events = EPOLLIN | EPOLLET | EPOLLOUT; ev.data.ptr = new ConnectionHandler(socketClient); if (epoll_ctl(hPoll,EPOLL_CTL_ADD,socketClient,&ev)) { ON_ERRNO(); return; } } void FCGI::ConnectionHandler::onRead() { TRACE_FN(ConnectionHandler::onRead); reader.onRead(socket); } void FCGI::ConnectionHandler::onWrite() { TRACE_FN(ConnectionHandler::onWrite); // TODO }