/*
 * This code is part of Screws project.
 * Copylefted by pancake@phreaker.net at 2003
 */

#if POLL

#include "Accept.h"
#include "Error.h"
#include "Logs.h"
#include "IO.h"

bool IO_poll(s,in,out,err)
	int s,in,out,err;
{
	struct pollfd pfd[3];
	register int i,j,n;
	int nb;
	char b[65556],*errbuf;
	int errlen=1024,errptr=0;

	pfd[0].fd=s;         /* stdin from socket */
	pfd[1].fd=out;  /* stdout|err from script */
	pfd[2].fd=err;
	
	for(i=0;i<3;i++)
	{
		pfd[i].events=POLLIN;
		pfd[i].revents=0;
	}

	errbuf=(char *)malloc(errlen);

	i=j=0;

	while(true)
	{
	n=poll(pfd,3,0);
	if (n==-1)
			{
			printf("POLL ERROR\n");
			return false;
			}
	if (n==0)
			{
			//printf("POLL ZERO\n");
			}
	if (n>0) { /* >= or > ???? */
		if (Svr.v>=V_SHOW)
		{
//			printf("Timeout\n"); 
		} 
		/* Capture Recive Events */
		if (pfd[0].revents) /* user input (PUT) */
		{
#if USESSL
			if (Svr.Lis[n].usessl)
				SSL_read((SSL *)pfd[0].fd, b, tcpwin);
			else
#endif
			nb=recv(pfd[0].fd,b,tcpwin,0);
			if (nb<=0) { close(pfd[0].fd); exit(0);} // Socket was closed unexpectedly
			write(in,b,nb);
		}
		if (pfd[1].revents) /* script stdout  */
		{
			nb=read(pfd[1].fd, b+j, tcpwin-j); 
			if (nb<=0)
			{
				return false;
			} else {
				j+=nb;
			}
		}
		
		if (j>=tcpwin)
		{
			setHTTPCode(b,j);
			if (!screws_send(s,b,j))
			{
				return false; // XXX log control-c ?
			}
			j=0;
		}
		   if (pfd[2].revents) /* script stderr */
		   {
			char bff[2];
			read(pfd[2].fd, bff,1);
			errbuf[errptr]=bff[0];
			errptr++;
			/* TODO Log errors */
		   }
		}

		/* wnohang childrens :) */
		if (!i) 
		{ 
			i=waitpid(-1,0,WNOHANG); 
			if (i==-1)i=0;
			usleep(Svr.usleep);
			continue;
			//usleep(Svr.usleep); 
			/* VIOLENCE!! */
		} 
		else 
		if (!n)
		{
			logSignal(i); 
			break;
		} /* Connection is done */
	} /* while */

#if 0
	if (Svr.v>=V_SHOW)
	{
		if (errptr)
		{
		errbuf[errptr]=0; /* EoS */
		printf("[stderr] '%s'\n",errbuf);
		}
	}
#endif
	
	/* send end of buffer ?? */
	if (j) 
	{
		setHTTPCode(b,j);
		if (!screws_send(s,b,j) ) // XXX errlog here?
			return true;
	}

	if (Svr.v>=V_EXEC)
		printf("SENT : %d bytes.\n",j);

	return true;
}
#endif

