/* Read the output data from the CGI script and return it to the client. This is called by the MPR in response to I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin. IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe) */ static void cgiCallback(MprCmd *cmd, int channel, void *data) { HttpConn *conn; Cgi *cgi; int suspended; if ((cgi = data) == 0) { return; } if ((conn = cgi->conn) == 0) { return; } conn->lastActivity = conn->http->now; switch (channel) { case MPR_CMD_STDIN: /* Stdin can absorb more data */ httpResumeQueue(cgi->writeq); break; case MPR_CMD_STDOUT: case MPR_CMD_STDERR: readFromCgi(cgi, channel); break; default: /* Child death notification */ if (cmd->status != 0) { httpError(cgi->conn, HTTP_CODE_BAD_GATEWAY, "Bad CGI process termination"); } break; } if (cgi->location) { httpRedirect(conn, conn->tx->status, cgi->location); } if (cmd->complete || cgi->location) { cgi->location = 0; httpFinalize(conn); mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0); return; } suspended = httpIsQueueSuspended(conn->writeq); assert(!suspended || conn->tx->writeBlocked); mprEnableCmdOutputEvents(cmd, !suspended); mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0); }
/* Read the output data from the CGI script and return it to the client. This is called by the MPR in response to I/O events from the CGI process for stdout/stderr data from the CGI script and for EOF from the CGI's stdin. IMPORTANT: This event runs on the connection's dispatcher. (ie. single threaded and safe) */ static void cgiCallback(MprCmd *cmd, int channel, void *data) { HttpConn *conn; Cgi *cgi; int suspended; if ((cgi = data) == 0) { return; } if ((conn = cgi->conn) == 0) { return; } conn->lastActivity = conn->http->now; mprTrace(6, "CGI: cgiCallback event channel %d", channel); switch (channel) { case MPR_CMD_STDIN: /* Stdin can absorb more data */ httpResumeQueue(cgi->writeq); break; case MPR_CMD_STDOUT: case MPR_CMD_STDERR: readFromCgi(cgi, channel); break; default: /* Child death notification */ break; } if (cgi->location) { httpRedirect(conn, conn->tx->status, cgi->location); } if (cmd->complete || cgi->location) { cgi->location = 0; httpFinalize(conn); mprCreateEvent(conn->dispatcher, "cgiComplete", 0, httpIOEvent, conn, 0); return; } suspended = httpIsQueueSuspended(conn->writeq); mprTrace(6, "CGI: %s CGI: cgiCallback. Conn->writeq %d", suspended ? "DISABLE" : "ENABLE", conn->writeq->count); assert(!suspended || conn->tx->writeBlocked); mprEnableCmdOutputEvents(cmd, !suspended); mprCreateEvent(conn->dispatcher, "cgi", 0, httpIOEvent, conn, 0); }