void serv_proc(int fd){ char buf[MAXLINE]; Req_header header; char delims[] = "/"; char *result = NULL; readline(fd, buf, MAXLINE); #ifdef DEBUG fprintf(stderr, "%s", buf); #endif parse_request(buf, &header); memset(buf, 0, MAXLINE); strcpy(buf, header.locator); result = strtok(buf, delims); if (strcmp(result, "cgi-bin") == 0) { cgi_handle(fd, &header); } else { http_respond(fd, &header); } servlog(LOG_INFO, "[client:%s][%s] %d\n", "192.168.1.1", "GET /index.html HTTP/1.1", 200); }
static void signalhld_handle(int sig) { hash_item_t * hitem; epoll_cgi_t * executeCgi; int i; int status; int pid = wait(&status); if(pid == SIGCHLD) { printf("why \n"); return; } for(i = 0; i < cgi_info_manager_gloabal->h->size; i++) { hitem = cgi_info_manager_gloabal->h->buckets[i].items; while(hitem) { if(hitem->type == HASH_ITEM_VALUE_TYPE_PTR) { executeCgi = (epoll_cgi_t *)hitem->value.ptr; if(executeCgi->pid == pid ) { executeCgi->status = CGI_STATUS_END; executeCgi->pid = 0; close(executeCgi->fd); close(executeCgi->pipe.in); close(executeCgi->pipe.out); pool_destroy(executeCgi->p); executeCgi->p = NULL; if(executeCgi->last_run_ts < executeCgi->last_add_ts) {//执行时间小于 executeCgi->status = CGI_STATUS_CLOSEING; cgi_handle(executeCgi, g_goabal); } } } hitem = hitem->next; } } }
int start_cgi(http_conf *g) { execute_cgi_info_manager_t * cgi_info_manager ; struct epoll_event ev[MAX_EVENT]; struct epoll_event *evfd ; int count; buffer *header; epoll_extra_data_t *epoll_data; int i = 0; hash_item_t * hitem; epoll_cgi_t * executeCgi; int evIndex; g_goabal = g; cgi_info_manager = cgi_info_manager_gloabal = initCgiManager(); header = buffer_create_size(cgi_info_manager->p, 1024); start_cgi_server(g, cgi_info_manager); printf("--------------- start execute sh server\n"); signal(SIGCHLD, signalhld_handle); while(1) { count = epoll_wait(g->epfd, ev, MAX_EVENT, -1); //收集所有需要需要执行cgi文件的 while(read_cgi_header(header, g->fd) == 0) { parse_cig_header(cgi_info_manager, header); header->used = 0; } //处理正在执行cgi文件 if(count < 0) { continue;} evfd = ev; for(evIndex = 0; evIndex < count; evIndex++){ if(evfd->events & EPOLLIN) { epoll_data = ev->data.ptr; switch(epoll_data->type) { case CGIFD: get_cgi_operator_handle((epoll_cgi_t *)epoll_data->ptr); break; } } evfd++; } //开始执行cgi任务, 其实可以用回调函数或者hash_filter返回可用的数据。然而我不回写如何将函数做为参数 for(i = 0; i < cgi_info_manager->h->size; i++) { hitem = cgi_info_manager->h->buckets[i].items; while(hitem) { if(hitem->type == HASH_ITEM_VALUE_TYPE_PTR) { executeCgi = (epoll_cgi_t *)hitem->value.ptr; if(executeCgi->status == CGI_STATUS_RUN && executeCgi->last_run_ts < executeCgi->last_add_ts) { printf("kill pid %d\n", executeCgi->pid); kill(executeCgi->pid, SIGKILL); } else if(executeCgi-> status != CGI_STATUS_CLOSEING ) { if(executeCgi->last_run_ts < executeCgi->last_add_ts ) {//执行时间小于 executeCgi->status = CGI_STATUS_CLOSEING; cgi_handle(executeCgi, g); } }else { printf("none \n"); } } hitem = hitem->next; } } } }