Esempio n. 1
0
/*
 *----------------------------------------------------------------------
 *
 * WriteCloseRecords --
 *
 *      Writes an EOF record for the stream content if necessary.
 *      If this is the last writer to close, writes an FCGI_END_REQUEST
 *      record.
 *
 *----------------------------------------------------------------------
 */
static void WriteCloseRecords(struct FCGX_Stream *stream)
{
	FCGX_Stream_Data *data = (FCGX_Stream_Data *) stream->data;
	/*
	 * Enter rawWrite mode so final records won't be encapsulated as
	 * stream data.
	 */
	data->rawWrite = TRUE;
	/*
	 * Generate EOF for stream content if needed.
	 */
	if (!(data->type == FCGI_STDERR
			&& stream->wrNext == data->buff
			&& !data->isAnythingWritten)) {
		FCGI_Header header;
		header = MakeHeader(data->type, data->reqDataPtr->requestId, 0,
			0);
		FCGX_PutStr((char *)&header, sizeof(header), stream);
	};
	/*
	 * Generate FCGI_END_REQUEST record if needed.
	 */
	if (data->reqDataPtr->nWriters == 1) {
		FCGI_EndRequestRecord endRequestRecord;
		endRequestRecord.header = MakeHeader(FCGI_END_REQUEST,
			data->reqDataPtr->requestId,
			sizeof(endRequestRecord.body), 0);
		endRequestRecord.body =
			MakeEndRequestBody(data->reqDataPtr->appStatus,
			FCGI_REQUEST_COMPLETE);
		FCGX_PutStr((char *)&endRequestRecord, sizeof(endRequestRecord),
			stream);
	}
	data->reqDataPtr->nWriters--;
}
Esempio n. 2
0
static int
flush_bufs(void)
{
	int r;

	r = obuf.ptr - obuf.buf;
	if (r)
	{
		FCGX_PutStr(obuf.buf, r, out);
		/*FCGI_fwrite(obuf.buf, 1, r, FCGI_stdout);*/
		obuf.ptr = obuf.buf;
	}
	r = ebuf.ptr - ebuf.buf;
	if (r)
	{
		FCGX_PutStr(ebuf.buf, r, err);
		/*FCGI_fwrite(ebuf.buf, 1, r, FCGI_stderr);*/
		ebuf.ptr = ebuf.buf;
	}

	/*r = FCGX_FFlush(out);*/
	/*r = FCGI_fflush(FCGI_stdout);*/
	/*FCGX_FFlush(err);*/
	/*FCGI_fflush(FCGI_stderr);*/

	return r;
}
Esempio n. 3
0
/*
 *	send response to server
 */
static void sendResponse(HTTPResponse *resp)
{
   String *resphdrs;
#ifndef PROFILE
   FCGX_FPrintF(out,"Status: %d %s" CRLF,resp->status,resp->statusMsg);
#endif

   resphdrs = resp_packageHeaders(resp);
#ifndef PROFILE
   FCGX_PutS(resphdrs->text,out);
#endif
   str_free(resphdrs);
#ifndef PROFILE
   FCGX_PutS(CRLF, out);
#endif

#ifndef PROFILE

   /* resp->content_valid will be 0 for HEAD requests and empty responses */
   if (resp->content_valid) {
      while (resp->content_read < resp->content_length) {
         //fwrite(resp->content,sizeof(char),resp->content_valid,stdout);
	      FCGX_PutStr(resp->content, resp->content_valid, out);
		 if (resp_getResponseContent(resp, 1) == -1)
         {
         	break;
         }
      }
      //fwrite(resp->content,sizeof(char),resp->content_valid,stdout);
      FCGX_PutStr(resp->content, resp->content_valid, out);
   }
   FCGX_FFlush(out);
#endif
   return;		
}
Esempio n. 4
0
/*
static int
tohex(char c)
{
    if (c>='0' && c<='9')
        return c-'0';
    if (c>='a' && c<='f')
        return c-'a'+10;
    if (c>='A' && c<='F')
        return c-'A'+10;
    return c;
}
*/
static int
handle_ctrl(FCGX_Request *request, char *bfr, int sz)
{
    struct netv_lua_widget *w;
    enum lua_cmd cmd;

    cmd = *bfr;
    bfr++;
    sz--;

    w = (struct netv_lua_widget *)bfr;
    bfr += sizeof(*w);
    sz -= sizeof(*w);

    if (sz < 0) {
        FCGX_FPrintF(request->out, "Content-Type: text/html\r\n"
                                   "Status: 500\r\n"
                                   "\r\n"
                                   "Not enough data to handle ctrl interface\r\n");
        return 0;
    }

    FCGX_FPrintF(request->out, "Content-Type: text/html\r\n"
                               "X-Handle: %d\r\n"
                               "X-%s: x=%d&y=%d&w=%d&h=%d&c1=%d&c2=%d&t=%d\r\n"
                               "\r\n",
                               w->id+HANDLE_OFFSET,
                               (cmd==LC_INPUT || cmd==LC_NEWINPUT)?"Input":"Output",
                               w->x, w->y, w->width, w->height,
                               w->color1, w->color2, w->type);
    if (cmd == LC_OUTPUT)
        FCGX_PutStr(bfr, sz, request->out);
    return 0;
}
Esempio n. 5
0
static void
output(sl_vm_t* vm, char* buff, size_t len)
{
    slash_context_t* ctx = vm->data;
    flush_headers(ctx);
    FCGX_PutStr(buff, (int)len, ctx->request.out);
}
Esempio n. 6
0
static void io_fcgi_write_headers(void *context, const char * const *headers, int num_headers)
{
	FCGX_Request *request = (FCGX_Request *)context;
	for(int i = 0; i < num_headers; i++) {
		FCGX_FPrintF(request->out, "%s\r\n", headers[i]);
	}
	FCGX_PutStr("\r\n", 2, request->out);
}
Esempio n. 7
0
size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp)
{
    int n;
    if(fp->stdio_stream)
        return fwrite(ptr, size, nmemb, fp->stdio_stream);
    else if(fp->fcgx_stream) {
        n = FCGX_PutStr((char *) ptr, size * nmemb, fp->fcgx_stream);
        return (n/size);
    }
    return EOF;
}
Esempio n. 8
0
static ssize_t
fcgi_stream_write(void *handle, char *buf, size_t size)
{
  FCGX_Stream *s;
  ssize_t bytes_written;

  s = handle;
  bytes_written = FCGX_PutStr(buf, size, s);

  return bytes_written;
}
Esempio n. 9
0
static VALUE fcgi_stream_write(VALUE self, VALUE str)
{
  FCGX_Stream *stream;
  int len;

  rb_secure(4);
  Data_Get_Struct(self, FCGX_Stream, stream);
  str = rb_obj_as_string(str);
  len = FCGX_PutStr(RSTRING_PTR(str), RSTRING_LEN(str), stream);
  if (len == EOF) CHECK_STREAM_ERROR(stream);
  return INT2NUM(len);
}
Esempio n. 10
0
size_t FCGI_fwrite(void *ptr, size_t size, size_t nmemb, FCGI_FILE *fp)
{
    int n;
    if(fp->stdio_stream)
        return fwrite(ptr, size, nmemb, fp->stdio_stream);
    else if(fp->fcgx_stream) {
        if((size * nmemb) == 0) {
            return 0;
        }
        ASSERT(size * nmemb < (size_t)INT_MAX);
        n = (size_t)FCGX_PutStr((char *) ptr, (int)(size * nmemb), fp->fcgx_stream);
        ASSERT(n >= 0);
        return ((size_t)n/size);
    }
    return (size_t)EOF;
}
Esempio n. 11
0
int
FastcgiRequest::write(const char *buf, int size) {
    int num = FCGX_PutStr(buf, size, fcgiRequest_.out);
    if (-1 == num) {
        std::stringstream str;
        int error = FCGX_GetError(fcgiRequest_.out);
        if (error > 0) {
            char buffer[256];
            str << "Cannot write data to fastcgi socket: " <<
                strerror_r(error, buffer, sizeof(buffer)) << ". ";
        }
        else {
            str << "FastCGI error. ";
        }
        generateRequestInfo(request_.get(), str);
        throw std::runtime_error(str.str());
    }
    return num;
}
Esempio n. 12
0
static int
request_write_(CONTAINER_REQUEST *me, const char *buf, size_t buflen)
{
	int r;
	
	if(!me->headers_sent)
	{
		cw_request_headers_send(&(me->headers), request_write_header_, me);
		FCGX_PutChar('\n', me->out);
		me->wbytes++;
		me->headers_sent = 1;
	}
	r = FCGX_PutStr(buf, buflen, me->out);
	if(r > 0)
	{
		me->wbytes += r;
	}
	return r;
}
Esempio n. 13
0
/* r:puts(string) */
int L_req_puts(lua_State *L) {
    request_t* r = NULL;
    const char* s = NULL;
    size_t l = 0;
    if (lua_gettop(L) >= 2) {
        r = luaL_checkrequest(L, 1);
        s = luaL_checklstring(L, 2, &l);
        if (r->buffering) {
        	/* add to output buffer */
        	buffer_add(&r->body, s, l);
        } else {
			/* make sure headers are sent before any data */
			if(!r->headers_sent)
				send_header(r);
			FCGX_PutStr(s, l, r->fcgi.out);
        }
    }
    return 0;
}
Esempio n. 14
0
static PyObject *
fcgi_Stream_write(fcgi_Stream *self, PyObject *args)
{
    int wrote;
    FCGX_Stream *s;
    int len;
    char *data;

    fcgi_Stream_Check();

    s = *(self->s);

    if (!PyArg_ParseTuple(args, "s#", &data, &len))
        return NULL;

    if (len == 0) {
        Py_RETURN_NONE;
    }

    Py_BEGIN_ALLOW_THREADS
    wrote = FCGX_PutStr(data, len, s);
    Py_END_ALLOW_THREADS

    if (wrote < len) {
        if (wrote < 0) {
            PyErr_SetString(PyExc_IOError, "Write failed");
        } else {
            char msgbuf[256];
            PyOS_snprintf(msgbuf, sizeof(msgbuf),
                  "Write failed, wrote %d of %d bytes",
                  wrote, len);
            PyErr_SetString(PyExc_IOError, msgbuf);
        }
        return NULL;
    }

    Py_RETURN_NONE;
}
Esempio n. 15
0
std::size_t
fastcgi::write(char const *buffer, std::size_t size) {
	assert(accepted());
	return static_cast<std::size_t>(FCGX_PutStr(buffer, size, req_.get()->out));
}
Esempio n. 16
0
/* This is a hacked version of Python's fileobject.c:file_writelines(). */
static PyObject *
fcgi_Stream_writelines(fcgi_Stream *self, PyObject *seq)
{
#define CHUNKSIZE 1000
    FCGX_Stream *s;
    PyObject *list, *line;
    PyObject *it;   /* iter(seq) */
    PyObject *result;
    int i, j, index, len, nwritten, islist;

    fcgi_Stream_Check();

    s = *(self->s);

    result = NULL;
    list = NULL;
    islist = PyList_Check(seq);
    if  (islist)
        it = NULL;
    else {
        it = PyObject_GetIter(seq);
        if (it == NULL) {
            PyErr_SetString(PyExc_TypeError,
                "writelines() requires an iterable argument");
            return NULL;
        }
        /* From here on, fail by going to error, to reclaim "it". */
        list = PyList_New(CHUNKSIZE);
        if (list == NULL)
            goto error;
    }

    /* Strategy: slurp CHUNKSIZE lines into a private list,
       checking that they are all strings, then write that list
       without holding the interpreter lock, then come back for more. */
    for (index = 0; ; index += CHUNKSIZE) {
        if (islist) {
            Py_XDECREF(list);
            list = PyList_GetSlice(seq, index, index+CHUNKSIZE);
            if (list == NULL)
                goto error;
            j = PyList_GET_SIZE(list);
        }
        else {
            for (j = 0; j < CHUNKSIZE; j++) {
                line = PyIter_Next(it);
                if (line == NULL) {
                    if (PyErr_Occurred())
                        goto error;
                    break;
                }
                PyList_SetItem(list, j, line);
            }
        }
        if (j == 0)
            break;

        /* Check that all entries are indeed strings. If not,
           apply the same rules as for file.write() and
           convert the results to strings. This is slow, but
           seems to be the only way since all conversion APIs
           could potentially execute Python code. */
        for (i = 0; i < j; i++) {
            PyObject *v = PyList_GET_ITEM(list, i);
            if (!PyString_Check(v)) {
                    const char *buffer;
                    int len;
                if (PyObject_AsReadBuffer(v,
                          (const void**)&buffer,
                                &len) ||
                     PyObject_AsCharBuffer(v,
                               &buffer,
                               &len)) {
                    PyErr_SetString(PyExc_TypeError,
            "writelines() argument must be a sequence of strings");
                    goto error;
                }
                line = PyString_FromStringAndSize(buffer,
                                  len);
                if (line == NULL)
                    goto error;
                Py_DECREF(v);
                PyList_SET_ITEM(list, i, line);
            }
        }

        /* Since we are releasing the global lock, the
           following code may *not* execute Python code. */
        Py_BEGIN_ALLOW_THREADS
        errno = 0;
        for (i = 0; i < j; i++) {
                line = PyList_GET_ITEM(list, i);
            len = PyString_GET_SIZE(line);
            nwritten = FCGX_PutStr(PyString_AS_STRING(line), len, s);
            if (nwritten != len) {
                Py_BLOCK_THREADS
                if (nwritten < 0) {
                    PyErr_SetString(PyExc_IOError, "Write failed");
                } else {
                    char msgbuf[256];
                    PyOS_snprintf(msgbuf, sizeof(msgbuf),
                          "Write failed, wrote %d of %d bytes",
                          nwritten, len);
                    PyErr_SetString(PyExc_IOError, msgbuf);
                }
                goto error;
            }
        }
        Py_END_ALLOW_THREADS

        if (j < CHUNKSIZE)
            break;
    }
Esempio n. 17
0
int lsp::io_def_write(void* ctx,const char* s,size_t len) {
	REQBAG *bag = (REQBAG*)ctx;
	
	output_headers(bag);
	return FCGX_PutStr(s, len, bag->out); 
}
Esempio n. 18
0
static int
nlua_webio(FCGX_Request *request, char *arg, int id)
{
    char *method = FCGX_GetParam("REQUEST_METHOD", request->envp);

    /* If it's a POST, then write to Lua's stdin */
    if (!strcmp(method, "POST")) {
        char bfr[8192];
        int bytes_read, bytes_written;
        int timeout = DEFAULT_WEBIO_TIMEOUT;
        if (*arg) {
            timeout = strtoul(arg, NULL, 0);
            if (timeout < 0 || timeout > MAX_WEBIO_TIMEOUT)
                timeout = DEFAULT_WEBIO_TIMEOUT;
        }


        FCGX_FPrintF(request->out, "Content-Type: text/html\r\n\r\n");
        while ( (bytes_read = FCGX_GetStr(bfr, sizeof(bfr), request->in)) > 0) {
            char *left = bfr;

            /*
            if (enc && (!strcmp(enc, "hex") || !strcmp(enc, "hexecho"))) {
                char *s = bfr;
                int input=0, output=0;
                while (input < bytes_read) {
                    s[output] = (tohex(s[input++])<<4)&0xf0;
                    if (s[input])
                        s[output] |= tohex(s[input++])&0x0f;
                    output++;
                }
                s[output] = '\0';
                bytes_read /= 2;
            }

            if (!strcmp(enc, "hexecho") || !strcmp(enc, "echo")) 
                FCGX_PutStr(bfr, bytes_read, request->out);
            */

            while (bytes_read > 0) {
                bytes_written = write(nlua_states[id].in_fd, left, bytes_read);
                if (bytes_written < 0) {
                    perror("Unable to write file");
                    return make_error(request, "Unable to write file", errno);
                }
                left += bytes_written;
                bytes_read -= bytes_written;
            }
        }
    }

    /* If it's not a POST, then read from stdout / stderr */
    else if (!strcmp(method, "GET")) {
        fd_set s;
        struct timeval t = {DEFAULT_WEBIO_TIMEOUT, 20000};
        int i;
        int read_fd, handle_id;
        int max;

        FD_ZERO(&s);

        FD_SET(nlua_states[id].out_fd, &s);
        max = nlua_states[id].out_fd;

        FD_SET(nlua_states[id].err_fd, &s);
        if (max < nlua_states[id].err_fd)
            max = nlua_states[id].err_fd;

        FD_SET(nlua_states[id].out_ctrl, &s);
        if (max < nlua_states[id].out_ctrl)
            max = nlua_states[id].out_ctrl;

        i = select(max+1, &s, NULL, NULL, &t);
        if (i > 0) {
            char bfr[16384];

            if (FD_ISSET(nlua_states[id].out_fd, &s)) {
                read_fd = nlua_states[id].out_fd;
                handle_id = 1;
            }

            else if (FD_ISSET(nlua_states[id].err_fd, &s)) {
                read_fd = nlua_states[id].err_fd;
                handle_id = 2;
            }

            else {
                read_fd = nlua_states[id].out_ctrl;
                handle_id = 3;
            }

            i = read(read_fd, bfr, sizeof(bfr));
            if (i == -1 && (errno == EINTR || errno == EAGAIN)) {
                
                /* Interrupted, but try again */
                FCGX_FPrintF(request->out, "Content-Type: text/html\r\n"
                                           "X-Handle: %d\r\n"
                                           "\r\n",
                                           handle_id);
                return 0;
            }

            else if (i == -1) {
                /* Unrecoverable error */
                kill(nlua_states[id].pid, SIGKILL);
                kill(nlua_states[id].pid, SIGTERM);
                close(nlua_states[id].out_fd);
                close(nlua_states[id].err_fd);
                close(nlua_states[id].out_ctrl);
                nlua_states[id].out_fd = -1;
                nlua_states[id].err_fd = -1;
                nlua_states[id].out_ctrl = -1;
                nlua_pool_status[id] = 0;
                return make_error(request, "Unable to read from handle", errno);
            }

            /* The handle control fd requires special care */
            else if (handle_id == 3)
                return handle_ctrl(request, bfr, i);

            else if (i == 0) {
                /* Connection closed */
                close(nlua_states[id].out_fd);
                close(nlua_states[id].err_fd);
                close(nlua_states[id].out_ctrl);
                nlua_states[id].out_fd = -1;
                nlua_states[id].err_fd = -1;
                nlua_states[id].out_ctrl = -1;
                nlua_pool_status[id] = 0;
                FCGX_FPrintF(request->out, "Content-Type: text/plain\r\n"
                                           "Status: 204\r\n"
                                           "X-Handle: %d\r\n"
                                           "\r\n",
                                           handle_id);
            }
            else {
                FCGX_FPrintF(request->out, "Content-Type: text/plain\r\n"
                                           "X-Handle: %d\r\n"
                                           "\r\n",
                                           handle_id);
                FCGX_PutStr(bfr, i, request->out);
            }
        }

        else if (!i || (i == -1 && (errno == EINTR || errno == EAGAIN))) {
            /* No data to read */
            FCGX_FPrintF(request->out, "Content-Type: text/html\r\n\r\n");
        }
        else {
            /* Error occurred */
            kill(nlua_states[id].pid, SIGKILL);
            kill(nlua_states[id].pid, SIGTERM);
            close(nlua_states[id].out_fd);
            close(nlua_states[id].err_fd);
            close(nlua_states[id].out_ctrl);
            nlua_states[id].out_fd = -1;
            nlua_states[id].err_fd = -1;
            nlua_states[id].out_ctrl = -1;
            nlua_pool_status[id] = 0;
            return make_error(request, "Unable to read from stdout", errno);
        }
    }


    else {
        return make_error(request, "Unrecognized http method", 0);
    }

    return 0;
}
Esempio n. 19
0
/*
 *----------------------------------------------------------------------
 *
 * FCGX_PutS --
 *
 *      Writes a character string to the output stream.
 *
 * Results:
 *      number of bytes written for normal return,
 *      EOF (-1) if an error occurred.
 *
 *----------------------------------------------------------------------
 */
int FCGX_PutS(const char *str, FCGX_Stream * stream)
{
	return FCGX_PutStr(str, strlen(str), stream);
}
Q_LONG FastCgiDevice::writeBlock( const char *data, Q_ULONG len )
{
	return FCGX_PutStr( data, len, m_stream );
}
Esempio n. 21
0
static int io_fcgi_write(void *context, const void *buffer, int size)
{
	FCGX_Request *request = (FCGX_Request *)context;
	return FCGX_PutStr((const char *)buffer, size, request->out);
}
size_t HttpResponseX::WriteByte(const void *buf, size_t buf_size){
    if(!m_header_sended){
        SendHeader();
    }
    return FCGX_PutStr((const char *)buf, (int)buf_size, request_->GetFCGX_Request()->out );
}
Esempio n. 23
0
int main(int argc, char **argv, char **envp)
{
    int count;
    FCGX_Stream *paramsStream;
    fd_set readFdSet, writeFdSet;
    int numFDs, selectStatus;
    unsigned char headerBuff[8];
    int headerLen, valueLen;
    char *equalPtr;
    FCGI_BeginRequestRecord beginRecord;
    int	doBind, doStart, nServers;
    char appPath[MAXPATHLEN], bindPath[MAXPATHLEN];

    if(ParseArgs(argc, argv, &doBind, &doStart,
		   (char *) &bindPath, (char *) &appPath, &nServers)) {
	fprintf(stderr,
"Usage:\n"
"    cgi-fcgi -f <cmdPath> , or\n"
"    cgi-fcgi -connect <connName> <appPath> [<nServers>] , or\n"
"    cgi-fcgi -start -connect <connName> <appPath> [<nServers>] , or\n"
"    cgi-fcgi -bind -connect <connName> ,\n"
"where <connName> is either the pathname of a UNIX domain socket\n"
"or (if -bind is given) a hostName:portNumber specification\n"
"or (if -start is given) a :portNumber specification (uses local host).\n");
	exit(1);
    }
    if(doBind) {
        appServerSock = OS_FcgiConnect(bindPath);
    }
    if(doStart && (!doBind || appServerSock < 0)) {
        FCGI_Start(bindPath, appPath, nServers);
        if(!doBind) {
            exit(0);
        } else {
            appServerSock = OS_FcgiConnect(bindPath);
	}
    }
    if(appServerSock < 0) {
        fprintf(stderr, "Could not connect to %s\n", bindPath);
        exit(errno);
    }
    /*
     * Set an arbitrary non-null FCGI RequestId
     */
    requestId = 1;
    /*
     * XXX: Send FCGI_GET_VALUES
     */

    /*
     * XXX: Receive FCGI_GET_VALUES_RESULT
     */

    /*
     * Send FCGI_BEGIN_REQUEST (XXX: hack, separate write)
     */
    beginRecord.header = MakeHeader(FCGI_BEGIN_REQUEST, requestId,
            sizeof(beginRecord.body), 0);
    beginRecord.body = MakeBeginRequestBody(FCGI_RESPONDER, TRUE);
    count = write(appServerSock, &beginRecord, sizeof(beginRecord));
    if(count != sizeof(beginRecord)) {
        exit(errno);
    }
    /*
     * Send environment to the FCGI application server
     */
    paramsStream = CreateWriter(appServerSock, requestId, 8192, FCGI_PARAMS);
    for( ; *envp != NULL; envp++) {
        equalPtr = strchr(*envp, '=');
        if(equalPtr  == NULL) {
            exit(1000);
        }
        valueLen = strlen(equalPtr + 1);
        FCGIUtil_BuildNameValueHeader(
                equalPtr - *envp,
                valueLen,
                &headerBuff[0],
                &headerLen);
        if(FCGX_PutStr((char *) &headerBuff[0], headerLen, paramsStream) < 0
                || FCGX_PutStr(*envp, equalPtr - *envp, paramsStream) < 0
                || FCGX_PutStr(equalPtr + 1, valueLen, paramsStream) < 0) {
            exit(FCGX_GetError(paramsStream));
        }
    }
    FCGX_FClose(paramsStream);
    FreeStream(&paramsStream);
    /*
     * Perform the event loop until AppServerReadHander sees FCGI_END_REQUEST
     */
    fromWS.stop = fromWS.next = &fromWS.buff[0];
    webServerReadHandlerEOF = FALSE;
    FD_ZERO(&readFdSet);
    FD_ZERO(&writeFdSet);
    numFDs = max(appServerSock, STDIN_FILENO) + 1;
    SetFlags(appServerSock, O_NONBLOCK);
    for(;;) {
        if((fromWS.stop == fromWS.next) && !webServerReadHandlerEOF) {
            FD_SET(STDIN_FILENO, &readFdSet);
        } else {
            FD_CLR(STDIN_FILENO, &readFdSet);
        }
        if(fromWS.stop != fromWS.next) {
            FD_SET(appServerSock, &writeFdSet);
        } else {
            FD_CLR(appServerSock, &writeFdSet);
        }
        FD_SET(appServerSock, &readFdSet);
        selectStatus = select(numFDs, &readFdSet, &writeFdSet, NULL, NULL);
        if(selectStatus < 0) {
            exit(errno);
        }
        if(selectStatus == 0) {
            /*
             * Should not happen, no select timeout.
             */
            continue;
        }
        if(FD_ISSET(STDIN_FILENO, &readFdSet)) {
            WebServerReadHandler();
        }
        if(FD_ISSET(appServerSock, &writeFdSet)) {
            AppServerWriteHandler();
        }
        if(FD_ISSET(appServerSock, &readFdSet)) {
            AppServerReadHandler();
	}
        if(exitStatusSet) {
            exit(exitStatus);
	}
    } 
}