int bit_file::load(const char* name) { FILE *f; int rc = -1; u8 field; if (data || length) // Call clear() first return -1; f = fopen(name, "rb"); if (f == NULL) { msgf(STR_UNABLE_TO_OPEN_FILE); return -1; } // Skip header fseek(f, 13, SEEK_SET); // Read fields while(!feof(f)) { if (fread(&field, 1, 1, f) != 1) goto cleanup; switch (field) { case 'a': // NCD File Name case 'b': // Part Name case 'c': // Creation Date case 'd': // Creation Time if (read_field(f, NULL, 0) != 0) { msgf(STR_INVALID_FILE_FORMAT); goto cleanup; } break; case 'e': // Data if (alloc_read_data(f) != 0) { msgf(STR_INVALID_FILE_FORMAT); goto cleanup; } rc = 0; goto cleanup; break; default: msgf(STR_INVALID_FILE_FORMAT); goto cleanup; } } cleanup: if (rc) clear(); if (f) fclose(f); return rc; }
static void *response_thread(void *args) { pthread_t thread_id; int has_method, sockfd; unsigned int n; ghd_task_t* task; ghd_method method; ghd_request_fields_t Connection_field; volatile p_read_data received_data = NULL; // 注册线程意外退出回调函数 // 强制类型转换,make gcc happy. pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, (void *)&mutex); thread_id = pthread_self(); syslog(LOG_INFO, "Thread ID: %ld", thread_id); /* 处理线程就在这个while 里循环, * 等待信号, 有信号就处理,处理完毕继续等待 */ while ( 1 ) { /* 在使用前一定要确保mutex已初始化 */ pthread_mutex_lock(&mutex); while(task_queue_head == NULL) pthread_cond_wait(&cond, &mutex); sockfd = task_queue_head->sockfd; task = task_queue_head; task_queue_head = task_queue_head->next; if (task_queue_head == NULL) task_queue_tail = NULL; geekhttpd_task_free(task); pthread_mutex_unlock(&mutex); received_data = alloc_read_data(); if (received_data == NULL) { syslog(LOG_INFO, "Cannot alloc memory for received_data"); goto closefd; } has_method = 0; /* 读取从客户端发来的清求 */ while (1) { /* 重置errno */ errno = 0; if ( received_data->len < MAXHEADERLEN) n = read(sockfd, received_data->data + received_data->len, MAXHEADERLEN - received_data->len); else break; if (n < 0) { if ( errno == EINTR) { continue; } /* 处理有问题的链接 */ syslog(LOG_INFO, "brower closed connection"); goto closefd; } else if (n == 0) { break; } else { if ( errno == EAGAIN ) break; received_data->len += n; if (!has_method && received_data->len > 7){ get_request_method(received_data->data, &method); has_method = 1; } } } syslog(LOG_INFO, "[Request] Size %d, Content: %s", received_data->len, \ (char *)received_data->data); /* * 根据方法响应请求,向浏览器发送消息和数据 */ switch (method) { case GET: do_get(sockfd, received_data); break; case POST: do_post(sockfd, received_data); break; case HEAD: do_head(sockfd, received_data); break; case PUT: case DELETE: case TRACE: case CONNECT: case OPTIONS: do_not_implement(sockfd); break; case UNKNOWN: /* send 405 */ do_unknown_method(sockfd); break; default: break; } /* TODO: * Connection: Keep-Alive * 没有处理 */ closefd: close(sockfd); /* free read_data */ free_read_data(received_data); received_data = NULL; } pthread_cleanup_pop(0); }