/* Any entry in the cgiList need to be checked to see if it has completed, and if so, process its output and clean up. Return time till next poll. */ WebsTime websCgiPoll() { Webs *wp; Cgi *cgip; char **ep; int cid, nTries; for (cid = 0; cid < cgiMax; cid++) { if ((cgip = cgiList[cid]) != NULL) { wp = cgip->wp; websCgiGatherOutput(cgip); if (checkCgi(cgip->handle) == 0) { /* We get here if the CGI process has terminated. Clean up. */ for (nTries = 0; (cgip->fplacemark == 0) && (nTries < 100); nTries++) { websCgiGatherOutput(cgip); /* There are some cases when we detect app exit before the file is ready. */ if (cgip->fplacemark == 0) { #if WINDOWS Sleep(10); #endif } } if (cgip->fplacemark == 0) { websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "CGI generated no output"); } else { trace(5, "cgi: Request complete - calling websDone"); websDone(wp); } /* Remove the temporary re-direction files */ unlink(cgip->stdIn); unlink(cgip->stdOut); /* Free all the memory buffers pointed to by cgip. The stdin file name (wp->cgiStdin) gets freed as part of websFree(). */ cgiMax = wfreeHandle(&cgiList, cid); for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) { wfree(*ep); } wfree(cgip->cgiPath); wfree(cgip->argp); wfree(cgip->envp); wfree(cgip->stdOut); wfree(cgip); websPump(wp); } } } return cgiMax ? 10 : MAXINT; }
/* Free a socket structure */ PUBLIC void socketFree(int sid) { WebsSocket *sp; char buf[256]; int i; if ((sp = socketPtr(sid)) == NULL) { return; } /* To close a socket, remove any registered interests, set it to non-blocking so that the recv which follows won't block, do a shutdown on it so peers on the other end will receive a FIN, then read any data not yet retrieved from the receive buffer, and finally close it. If these steps are not all performed RESETs may be sent to the other end causing problems. */ socketRegisterInterest(sid, 0); if (sp->sock >= 0) { socketSetBlock(sid, 0); while (recv(sp->sock, buf, sizeof(buf), 0) > 0) {} if (shutdown(sp->sock, SHUT_RDWR) >= 0) { while (recv(sp->sock, buf, sizeof(buf), 0) > 0) {} } closesocket(sp->sock); } wfree(sp->ip); wfree(sp); socketMax = wfreeHandle(&socketList, sid); /* Calculate the new highest socket number */ socketHighestFd = -1; for (i = 0; i < socketMax; i++) { if ((sp = socketList[i]) == NULL) { continue; } socketHighestFd = max(socketHighestFd, sp->sock); } }