WebRequest *FCGIStream::getNextRequest(int timeoutsec) { fd_set rfds; FD_ZERO(&rfds); FD_SET(0, &rfds); struct timeval timeout; timeout.tv_sec = timeoutsec; timeout.tv_usec = 0; for(;;) { int result = select(FD_SETSIZE, &rfds, 0, 0, &timeout); if (result == 0) return 0; // timeout else if (result == -1) { if (errno != EINTR) { perror("select"); exit(1); // FIXME: throw exception } else ; // EINTR, try again } else break; } FCGX_Request *request = new FCGX_Request(); FCGX_InitRequest(request, 0, 0); if (FCGX_Accept_r(request) == 0) { return new FCGIRequest(request); } else { LOG_ERROR("could not FCGX_Accept ?"); delete request; exit(1); // FIXME: throw exception } }
int main(int argc, char** argv){ (void)argc; (void)argv; openlog("eqbeats", LOG_PID, LOG_USER); struct eqbeats_ctx eq; if(eqbeats_init(&eq, "", NULL, EQBEATS_INIT_SETUP) != 0){ log("eqbeats initialization failed"); exit(1); } setenv("EQBEATS_DIR", eq.root, 0); DB::setPgDatabase(eq.pg); if(!DB::connect((std::string)argv[0] + "-" + number(getpid()))){ log("critical error: couldn't connect to PostgreSQL"); exit(1); } uint32_t buf = 0; int urandom = open("/dev/urandom", O_RDONLY); if(urandom != -1) { read(urandom, &buf, 4); close(urandom); srand(buf); } else { log("Couldn't open /dev/urandom, random seed will be predictable."); srand(getpid() ^ time(NULL)); } MagickWandGenesis(); FCGX_Request request; FCGX_Init(); FCGX_InitRequest(&request, 0, 0); FCgiIO o; ctemplate::AddModifier("x-irc", new IrcEscape); ctemplate::AddXssSafeModifier("x-email", new EmailEscape); ctemplate::AddXssSafeModifier("x-format", new Formatter); cache.SetTemplateRootDirectory(TEMPLATES_DIR); void (*callbacks[])(Document*) = { Pages::statics, Pages::home, Pages::track, Pages::trackMisc, Pages::tracks, Pages::oembed, Pages::trackActions, Pages::trackUpload, Pages::art, Pages::license, Pages::account, Pages::login, Pages::user, Pages::users, Pages::registration, Pages::passwordReset, Pages::playlist, Pages::playlistActions, Pages::comment, Pages::socialActions, Pages::favorites, Pages::featureActions, #ifdef HAVE_LIBHIREDIS Pages::stats, #endif 0 }; struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = &signalCatch; sigaction(SIGINT, &sa, NULL); sigaction(SIGQUIT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); pid_t child; int rc; while(FCGX_Accept_r(&request) == 0){ resetTimer(); if(eqbeats_health_check(&eq) < 0) continue; /* let it return 502 */ DB::healthCheck(); /* redis */ headers = request.envp; o.attach(&request); try { cgi = cgicc::Cgicc(&o); } catch(std::runtime_error &err){ log((std::string)"CgiCc error: " + err.what()); //continue; } path = stripSlash(cgi.getEnvironment().getScriptName()); Document doc; // Nope if (cgi.getElementByValue("PHPE9568F34-D428-11d2-A769-00AA001ACF42") != cgi.getElements().end() || cgi.getElementByValue("PHPE9568F35-D428-11d2-A769-00AA001ACF42") != cgi.getElements().end() || cgi.getElementByValue("PHPE9568F36-D428-11d2-A769-00AA001ACF42") != cgi.getElements().end()){ doc.redirect("http://youtu.be/gvdf5n-zI14"); } if (getenv("EQBEATS_HTTPS") && !cgi.getEnvironment().usingHTTPS() && cgi.getElements().size() == 0) doc.moved(eqbeatsUrl() + path); Session::start(); for(int i=0; !doc && callbacks[i]; i++) callbacks[i](&doc); Session::fill(doc.rootDict()); o << doc.generate(); Session::destroy(); FCGX_Finish_r(&request); while((child = waitpid(-1, &rc, WNOHANG)) > 0) // wait for zombies syslog(WIFEXITED(rc) ? LOG_NOTICE : LOG_ERR, "%d exited with %d.", child, WEXITSTATUS(rc)); } MagickWandTerminus(); DB::close(); eqbeats_end(&eq); return 0; }
static VALUE fcgi_s_accept(VALUE self) { int status; FCGX_Request *req; fd_set readfds; req = ALLOC(FCGX_Request); status = FCGX_InitRequest(req,0,0); if (status != 0) { rb_raise(eFCGIError, "FCGX_Init() failed"); return Qnil; } FD_ZERO(&readfds); FD_SET(req->listen_sock, &readfds); if (select(req->listen_sock+1, &readfds, NULL, NULL, NULL) < 1) { return Qnil; } status = FCGX_Accept_r(req); if (status >= 0) { fcgi_data *data; fcgi_stream_data *stream_data; char **env; VALUE obj,key, value; char *pkey,*pvalue; int flags, fd; /* Unset NONBLOCKING */ fd = ((FCGX_Request*) req)->ipcFd; flags = fcntl(fd, F_GETFL); if (flags & O_NONBLOCK) { fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); } obj = Data_Make_Struct(self, fcgi_data, fcgi_mark, fcgi_free_req, data); data->req = req; data->in = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data); stream_data->stream = req->in; stream_data->req = obj; data->out = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data); stream_data->stream = req->out; stream_data->req = obj; data->err = Data_Make_Struct(cFCGIStream, fcgi_stream_data, fcgi_stream_mark, fcgi_stream_free, stream_data); stream_data->stream = req->err; stream_data->req = obj; data->env = rb_hash_new(); env = req->envp; for (; *env; env++) { int size = 0; pkey = *env; pvalue = pkey; while( *(pvalue++) != '=') size++; key = rb_str_new(pkey, size); value = rb_str_new2(pvalue); OBJ_TAINT(key); OBJ_TAINT(value); rb_hash_aset(data->env, key, value); } return obj; } else { FCGX_Free(req, 1); free(req); return Qnil; } }
/* TODO: Comment */ static void *doit(void *a){ int rc, thread_id = (pthread_t) a; FCGX_Request request; apr_pool_t* pool; struct range_request* rr; struct libcrange *lr; char *config_file = NULL; char * r_query; /* range query */ int r_status = 0; apr_initialize(); atexit(apr_terminate); apr_pool_create(&pool, NULL); config_file = LIBCRANGE_CONF; lr = libcrange_new(pool, config_file); /* malloc for query */ r_query = (char *)malloc(QUERY_STR_SIZE); FCGX_InitRequest(&request, 0, 0); for (;;) { static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; apr_pool_t* sub_pool; apr_pool_create(&sub_pool, pool); /* zero it out */ bzero(r_query, QUERY_STR_SIZE); r_status = 0; /* Some platforms require accept() serialization, some don't.. */ pthread_mutex_lock(&accept_mutex); rc = FCGX_Accept_r(&request); pthread_mutex_unlock(&accept_mutex); if (rc < 0) break; r_status = get_range_query(&request, r_query); rr = range_expand(lr, sub_pool, r_query); FCGX_FPrintF(request.out, "Content-type: text/plain\r\n"); /* set headers */ if (range_request_has_warnings(rr)) { const char *warnings = range_request_warnings(rr); FCGX_FPrintF(request.out, "RangeException: %s\r\nRange_FCGI_Thread_Id: %d\r\n", warnings, thread_id); } /* End Delimiter */ FCGX_FPrintF(request.out, "\r\n"); /* r_status == 1, then wants list */ if (r_status == 1) { const char **nodes = range_request_nodes(rr); while(*nodes) { FCGX_FPrintF(request.out, "%s\n", *nodes++); } } else if (r_status == 0) { FCGX_FPrintF(request.out, "%s\n", range_request_compressed(rr)); } apr_pool_destroy(sub_pool); FCGX_Finish_r(&request); } /* for (;;) */ /* free, what I hogged :-) */ free(r_query); apr_pool_destroy(pool); return NULL; }
Worker4CloseThread() { FCGX_InitRequest(&request, 0, 0); }
static void *doit(int id, Config &conf) { FCGX_Request request; if(FCGX_InitRequest(&request, socketId.load(), 0) != 0) { //ошибка при инициализации структуры запроса printf("Can not init request\n"); return NULL; } Router router(&request, &conf); router.addHandler("OPTIONS", "/users/login", &OptUsersLogin); router.addHandler("GET", "/users/login", &UsersInfo); router.addHandler("POST", "/users/login", &PostUsersLogin); router.addHandler("OPTIONS", "/users/add", &OptUsersAdd); router.addHandler("POST", "/users/add", &PostUsersAdd); router.addHandler("OPTIONS", ".*", &OptDirs); router.addHandler("OPTIONS", "/dirs/(?<id>\\d+)", &OptDirs); router.addHandler("POST", "/dirs", &PostCreateDir); router.addHandler("GET", "/dirs/(\\d+)", &GetDir); router.addHandler("DELETE", "/dirs/(\\d+)", &DelDir); router.addHandler("POST", "/files/(\\d+)/(.+)", &PutFile); router.addHandler("GET", "/files/(\\d+)", &GetFile); router.addHandler("DELETE", "/files/(\\d+)", &DelFile); for(;;) { static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&accept_mutex); int rc = FCGX_Accept_r(&request); pthread_mutex_unlock(&accept_mutex); if(rc < 0) { //ошибка при получении запроса printf("Can not accept new request\n"); break; } std::streambuf * cin_streambuf = std::cin.rdbuf(); std::streambuf * cout_streambuf = std::cout.rdbuf(); std::streambuf * cerr_streambuf = std::cerr.rdbuf(); fcgi_streambuf cin_fcgi_streambuf(request.in); fcgi_streambuf cout_fcgi_streambuf(request.out); fcgi_streambuf cerr_fcgi_streambuf(request.err); std::cin.rdbuf(&cin_fcgi_streambuf); std::cout.rdbuf(&cout_fcgi_streambuf); std::cerr.rdbuf(&cerr_fcgi_streambuf); try { router.Run(); } catch (Error &e) { router.SetStatus(e.http_code()); router.AddHeader("Content-Type", "application/json; charset=utf-8"); router.AddContent(e.what()); router.AcceptContent(); } catch (std::exception &e) { std::cerr << e.what(); router.SetStatus(Httpstatus::InternalServerError); router.AddHeader("Content-Type", "text/plain; charset=utf-8"); router.AddContent(e.what()); router.AcceptContent(); } FCGX_Finish_r(&request); //завершающие действия - запись статистики, логгирование ошибок и т.п. router.Cleanup(); std::cin.rdbuf(cin_streambuf); std::cout.rdbuf(cout_streambuf); std::cerr.rdbuf(cerr_streambuf); } return NULL; }
void init() override { FCGX_InitRequest(&m_request, 0, 0); }
void* Rok4Server::thread_loop ( void* arg ) { Rok4Server* server = ( Rok4Server* ) ( arg ); FCGX_Request fcgxRequest; if ( FCGX_InitRequest ( &fcgxRequest, server->sock, FCGI_FAIL_ACCEPT_ON_INTR ) !=0 ) { LOGGER_FATAL ( _ ( "Le listener FCGI ne peut etre initialise" ) ); } while ( server->isRunning() ) { std::string content; bool postRequest; int rc; if ( ( rc=FCGX_Accept_r ( &fcgxRequest ) ) < 0 ) { if ( rc != -4 ) { // Cas différent du redémarrage LOGGER_ERROR ( _ ( "FCGX_InitRequest renvoie le code d'erreur" ) << rc ); } //std::cerr <<"FCGX_InitRequest renvoie le code d'erreur" << rc << std::endl; break; } //DEBUG: La boucle suivante permet de lister les valeurs dans fcgxRequest.envp /*char **p; for (p = fcgxRequest.envp; *p; ++p) { LOGGER_DEBUG((char*)*p); }*/ Request* request; postRequest = ( server->servicesConf.isPostEnabled() ?strcmp ( FCGX_GetParam ( "REQUEST_METHOD",fcgxRequest.envp ),"POST" ) ==0:false ); if ( postRequest ) { // Post Request char* contentBuffer = ( char* ) malloc ( sizeof ( char ) *200 ); while ( FCGX_GetLine ( contentBuffer,200,fcgxRequest.in ) ) { content.append ( contentBuffer ); } free ( contentBuffer ); contentBuffer= NULL; LOGGER_DEBUG ( _ ( "Request Content :" ) << std::endl << content ); request = new Request ( FCGX_GetParam ( "QUERY_STRING", fcgxRequest.envp ), FCGX_GetParam ( "HTTP_HOST", fcgxRequest.envp ), FCGX_GetParam ( "SCRIPT_NAME", fcgxRequest.envp ), FCGX_GetParam ( "HTTPS", fcgxRequest.envp ), content ); } else { // Get Request /* On espère récupérer le nom du host tel qu'il est exprimé dans la requete avec HTTP_HOST. * De même, on espère récupérer le path tel qu'exprimé dans la requête avec SCRIPT_NAME. */ request = new Request ( FCGX_GetParam ( "QUERY_STRING", fcgxRequest.envp ), FCGX_GetParam ( "HTTP_HOST", fcgxRequest.envp ), FCGX_GetParam ( "SCRIPT_NAME", fcgxRequest.envp ), FCGX_GetParam ( "HTTPS", fcgxRequest.envp ) ); } server->processRequest ( request, fcgxRequest ); delete request; FCGX_Finish_r ( &fcgxRequest ); FCGX_Free ( &fcgxRequest,1 ); } LOGGER_DEBUG ( _ ( "Extinction du thread" ) ); Logger::stopLogger(); return 0; }
void WebInterface::worker() { /* Backup the stdio streambufs */ std::streambuf * cin_streambuf = std::cin.rdbuf(); std::streambuf * cout_streambuf = std::cout.rdbuf(); std::streambuf * cerr_streambuf = std::cerr.rdbuf(); const std::string kw_title(KW_TITLE); const std::string kw_head(KW_HEAD); const std::string kw_menu(KW_MENU); const std::string kw_content(KW_CONTENT); FCGX_Request request; /* Initialize FastCGI library and request */ FCGX_Init(); FCGX_InitRequest(&request, 0, FCGI_FAIL_ACCEPT_ON_INTR); LOG_DBG("FastCGI initialization success!"); while (!stop_flag_) { if(FCGX_Accept_r(&request) >= 0) { fcgi_streambuf cin_fcgi_streambuf(request.in); fcgi_streambuf cout_fcgi_streambuf(request.out); fcgi_streambuf cerr_fcgi_streambuf(request.err); std::cin.rdbuf(&cin_fcgi_streambuf); std::cout.rdbuf(&cout_fcgi_streambuf); std::cerr.rdbuf(&cerr_fcgi_streambuf); /* getting the uri from the request */ std::string uri; const char *uri_param = FCGX_GetParam("REQUEST_URI", request.envp); if(!uri_param) { LOG_ERR("Failed to retrieve the request URI environment value!"); uri = URI_PAGE_ERROR; } else { uri = uri_param; } LOG_DBG("Request received: %s", uri.c_str()); /* Check if URI is a file in the home folder and get the mime of * that file (by extension) */ std::string path; std::string mime = if_file_get_mime(uri, &path); if (!mime.empty()) { /* This is a file we need to serve */ StringPtr file_data = Utils::read_file(path); std::cout << "Content-type: " << mime << "\r\n\r\n"; std::cout << *(file_data); file_data.reset(); } else { /* Parse the URI */ std::map<std::string, std::string> uri_data = parseURI(uri); LOG_DBG("URI Parsed, page requested: %s", uri_data[URI_PAGE].c_str()); /* Generate and serve the page depending on the URI */ StringPtr page; std::string content_type = "text/html"; /* Main page requested */ if (uri_data[URI_PAGE].compare(URI_PAGE_MAIN) == 0) { bool success = false; /* Check if a command was sent from the client. */ if (uri_data.find(URI_PAGE_COMMAND) != uri_data.end()) { success = add_command(uri_data[URI_PAGE_COMMAND]); } std::string s; /* Check if the request was sent from javascript or pure HTML */ if(uri_data.find(URI_PAGE_SOURCE) != uri_data.end()) { LOG_DBG("This query's source IS javascript: %s, Source: %s", uri.c_str(), (uri_data[URI_PAGE_SOURCE]).c_str()); content_type = "application/json"; page = generate_command_json(success); } else { LOG_DBG("This query's source IS NOT javascript: %s", uri.c_str()); /* Just generate a standard main page */ page = generate_main_page(); } /* Log page requested */ } else if (uri_data[URI_PAGE].compare(URI_PAGE_LOG) == 0) { page = generate_log_page(); /* Status page requested */ } else if (uri_data[URI_PAGE].compare(URI_PAGE_STATUS) == 0) { page = generate_status_page(); /* Console lines JSON page requested */ } else if (uri_data[URI_PAGE].compare(URI_PAGE_CL) == 0) { if (uri_data.find(URI_PAGE_BEFORE) != uri_data.end()) { content_type = "application/json"; page = generate_cljson_before( uri_data[URI_PAGE_BEFORE]); } else if (uri_data.find(URI_PAGE_AFTER) != uri_data.end()) { content_type = "application/json"; page = generate_cljson_after(uri_data[URI_PAGE_AFTER]); } else { page = generate_error_page(); } /* Log lines JSON page requested */ } else if (uri_data[URI_PAGE].compare(URI_PAGE_LL) == 0) { if (uri_data.find(URI_PAGE_BEFORE) != uri_data.end()) { content_type = "application/json"; page = generate_lljson_before( uri_data[URI_PAGE_BEFORE]); } else if (uri_data.find(URI_PAGE_AFTER) != uri_data.end()) { content_type = "application/json"; page = generate_lljson_after(uri_data[URI_PAGE_AFTER]); } else { page = generate_error_page(); } } else { page = generate_error_page(); } /* Output the generated page with the correct content type */ std::cout << "Content-type: " << content_type << "\r\n\r\n"; std::cout << *(page.get()); } } else { LOG_TRC("FCGX_Aceept_r returned less than 0!"); } } LOG_TRC("Out of accept request loop!"); // Free request strucure FCGX_Finish_r(&request); // Flag the thread as not running anymore. running_ = false; // restore stdio streambufs std::cin.rdbuf(cin_streambuf); std::cout.rdbuf(cout_streambuf); std::cerr.rdbuf(cerr_streambuf); }
int main(void) { unsigned int count = 0; int socket_fdescriptor = 0; char *buf = NULL; FCGX_Request request; Request_t req; // Initialize all the elements of the structures to NULL memset(&request, 0, sizeof(FCGX_Request) ); memset(&req, 0, sizeof(Request_t) ); if ( FCGX_Init() != 0 ) { return (1); } socket_fdescriptor = FCGX_OpenSocket(PORT_FCGI, 500); if ( socket_fdescriptor < 0 ) { return (2); } buf = (char *) malloc(50 * sizeof(char) ); sprintf(buf, "The file descriptor of the socket is : %d", socket_fdescriptor); logger("main.c", buf); if ( buf ) { free(buf); } if ( FCGX_InitRequest(&request, socket_fdescriptor, 0) < 0 ) { return (3); } /* Response loop. */ while ( FCGX_Accept_r(&request) == 0 ) { request_fill(request, &req); request_display(req, ++count); FCGX_FPrintF(request.out, "Content-type: text/html\r\n" "\r\n" "<title>FastCGI Hello! (C, fcgi_stdio library)</title>" "<h1>FastCGI Hello! (C, fcgi_stdio library)</h1>" "Request number %d", count); FCGX_Finish_r(&request); } fprintf(stderr, "Error FCGX_Accept_r"); return (0); }
int main(int argc, char* argv[], char* envp[]) { if(argc < 7) usage(argv); char* root = argv[1]; char* thumbnail_root = argv[2]; char* listen_addr = argv[3]; num_workers = atoi(argv[6]); if(num_workers < 1) usage(argv); struct passwd* pwd = getpwnam(argv[4]); if (pwd == NULL) error_errno("getpwnam_r failed", EXIT_FAILURE); struct group* grp = getgrnam(argv[5]); if (grp == NULL) error_errno("getgrnam_r failed", EXIT_FAILURE); int userid = pwd->pw_uid; int groupid = grp->gr_gid; if(root[strlen(root) - 1] != '/' || thumbnail_root[strlen(thumbnail_root) - 1] != '/') error("Did you forget the ending slash in the (thumbnail) root directory path?", EXIT_FAILURE); // TODO Some more error checking // Initialize syslog syslog(LOG_INFO, "Starting up\n"); #if defined(DEBUG) setlogmask(LOG_UPTO(LOG_DEBUG)); openlog("fastresize", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER); #else setlogmask(LOG_UPTO(LOG_INFO)); openlog("fastresize", LOG_CONS, LOG_USER); #endif // Change the working directory if((chdir(root)) < 0) error("Couldn't change working directory\n", EXIT_FAILURE); // Initialize FastCGI syslog(LOG_INFO, "Initializing FastCGI\n"); if(FCGX_Init()) error("Could not initialize FastCGI (during FCGX_Init())", EXIT_FAILURE); int listen_socket = FCGX_OpenSocket(listen_addr, 400); if(listen_socket < 0) error("Couldn't bind to FastCGI socket", EXIT_FAILURE); // Now that we've got our socket, drop root privileges if (getuid() == 0) { if (setgid(groupid) != 0) error_errno("setgid: Unable to drop group privileges", EXIT_FAILURE); if (setuid(userid) != 0) error_errno("setuid: Unable to drop user privileges", EXIT_FAILURE); } FCGX_Request request; if(FCGX_InitRequest(&request, listen_socket, 0)) error("Couldn't initialize FastCGI request handler", EXIT_FAILURE); // Initialize ImageMagick syslog(LOG_INFO, "Initializing ImageMagick\n"); MagickWandGenesis(); atexit(MagickWandTerminus); /* Fork a new master process to daemonize and exit the old one. We use * _Exit here to not trigger the atexit that terminates ImageMagick. */ if(fork()) _Exit(EXIT_SUCCESS); // Fork worker processes syslog(LOG_INFO, "Forking workers\n"); worker_pids = calloc(num_workers, sizeof(pid_t)); if(!worker_pids) error_errno("worker_pids: Could not allocate", 1); for(worker_id = 0; worker_id <= num_workers; worker_id++) { worker_pids[worker_id] = fork(); // Exit the loop if we're the forked process if(worker_pids[worker_id] == 0) break; syslog(LOG_INFO, "Forked worker with PID %d\n", worker_pids[worker_id]); } // The following code is only executed in the master process. if(worker_id > num_workers) { syslog(LOG_INFO, "master (PID %d): Sleeping until I receive a signal.\n", getpid()); /* Sleep a little until we get a SIG{TERM,HUP,INT} or one of our * workers died (not cool). */ struct sigaction exit_action; exit_action.sa_handler = &exit_signal; exit_action.sa_sigaction = &exit_signal; struct sigaction worker_died_action; worker_died_action.sa_handler = &worker_died; worker_died_action.sa_sigaction = &worker_died; sigaction(SIGTERM, &exit_action, NULL); sigaction(SIGHUP, &exit_action, NULL); sigaction(SIGINT, &exit_action, NULL); sigaction(SIGCHLD, &worker_died_action, NULL); pause(); // This should never™ be reached unless something funny happens. exit(EXIT_FAILURE); } syslog(LOG_INFO, "Worker #%d is now listening for requests on 127.0.0.1:9000\n", worker_id); while(FCGX_Accept_r(&request) == 0) handle_request(&request, root, thumbnail_root); // Exit exit(EXIT_SUCCESS); }
foreign_t fcgi_accept(control_t h) { FCGX_Request *req; fd_set fds; fcgi_context *ctxt; int status; FCGI_debug("fcgi_accept()"); if ( FCGX_IsCGI() ) { return TRUE; } ctxt = pthread_getspecific(key); if ( !ctxt ) { ctxt = malloc(sizeof(*ctxt)); memset(ctxt, 0, sizeof(*ctxt)); } if ( ctxt->req ) { fcgi_finish(); } req = malloc(sizeof(*req)); memset(req, 0, sizeof(*req)); status = FCGX_InitRequest(req, 0, 0); if ( status != FCGI_SUCCESS ) { return fcgi_raise_error(status, "FCGX_InitRequest() failed"); } FD_ZERO(&fds); FD_SET(req->listen_sock, &fds); if ( select(req->listen_sock+1, &fds, NULL, NULL, NULL) < 1 ) { return FALSE; } status = FCGX_Accept_r(req); if ( status != FCGI_SUCCESS ) { return fcgi_raise_error(status, "FCGX_Accept_r() failed"); } FCGI_debug("REMOTE_ADDR: %s, REQUEST_METHOD: %s, REQUEST_URI: %s", FCGX_GetParam("REMOTE_ADDR", req->envp), FCGX_GetParam("REQUEST_METHOD", req->envp), FCGX_GetParam("REQUEST_URI", req->envp)); if ( !ctxt ) { ctxt = malloc(sizeof(*ctxt)); memset(ctxt, 0, sizeof(*ctxt)); } ctxt->req = req; ctxt->pl_in = Suser_input; ctxt->h_in = Suser_input->handle; ctxt->fn_in = Suser_input->functions; ctxt->fcgi_in = req->in; ctxt->pl_out = Suser_output; ctxt->h_out = Suser_output->handle; ctxt->fn_out = Suser_output->functions; ctxt->fcgi_out = req->out; ctxt->pl_err = Suser_error; ctxt->h_err = Suser_error->handle; ctxt->fn_err = Suser_error->functions; ctxt->fcgi_err = req->err; ctxt->env = req->envp; pthread_setspecific(key, ctxt); Suser_input->handle = req->in; Suser_input->functions = &fcgi_functions; Suser_output->handle = req->out; Suser_output->functions = &fcgi_functions; Suser_error->handle = req->err; Suser_error->functions = &fcgi_functions; PL_retry(0); }