/* Initialize the filesystem. */ int dfs_init_pc(void *base_fs_loc, int tries) { /* Check to see if it passes the check */ while(tries != 0) { directory_entry_t id_node; grab_sector(base_fs_loc, &id_node); if(id_node.flags == FLAGS_ID && id_node.next_entry == NEXTENTRY_ID) { /* Passes, set up the FS */ base_ptr = base_fs_loc; clear_directory(); memset(open_files, 0, sizeof(open_files)); /* Good FS */ return DFS_ESUCCESS; } tries--; } /* Failed! */ return DFS_EBADFS; }
/* * `untracked_files` will be filled with the names of untracked files. * The return value is: * * = 0 if there are not any untracked files * > 0 if there are untracked files */ static int get_untracked_files(struct pathspec ps, int include_untracked, struct strbuf *untracked_files) { int i; int max_len; int found = 0; char *seen; struct dir_struct dir; memset(&dir, 0, sizeof(dir)); if (include_untracked != INCLUDE_ALL_FILES) setup_standard_excludes(&dir); seen = xcalloc(ps.nr, 1); max_len = fill_directory(&dir, the_repository->index, &ps); for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; if (dir_path_match(&the_index, ent, &ps, max_len, seen)) { found++; strbuf_addstr(untracked_files, ent->name); /* NUL-terminate: will be fed to update-index -z */ strbuf_addch(untracked_files, 0); } free(ent); } free(seen); free(dir.entries); free(dir.ignored); clear_directory(&dir); return found; }
/** * Recursively free a directory and all its contents. */ static void delete_directory(struct directory *directory) { assert(directory->parent != NULL); clear_directory(directory); dirvec_delete(&directory->parent->children, directory); directory_free(directory); }
void load_instrument_load_page(struct page *page) { clear_directory(); page->title = "Load Instrument"; page->draw_const = load_instrument_draw_const; page->set_page = load_instrument_set_page; page->handle_key = load_instrument_handle_key; page->total_widgets = 1; page->widgets = widgets_loadinst; page->help_index = HELP_GLOBAL; create_other(widgets_loadinst + 0, 0, file_list_handle_key, file_list_draw); widgets_loadinst[0].accept_text = 1; }
static void wt_status_collect_untracked(struct wt_status *s) { int i; struct dir_struct dir; struct timeval t_begin; if (!s->show_untracked_files) return; if (advice_status_u_option) gettimeofday(&t_begin, NULL); memset(&dir, 0, sizeof(dir)); if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES) dir.flags |= DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; if (s->show_ignored_files) dir.flags |= DIR_SHOW_IGNORED_TOO; setup_standard_excludes(&dir); fill_directory(&dir, s->pathspec); for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; if (cache_name_is_other(ent->name, ent->len) && match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) string_list_insert(&s->untracked, ent->name); free(ent); } for (i = 0; i < dir.ignored_nr; i++) { struct dir_entry *ent = dir.ignored[i]; if (cache_name_is_other(ent->name, ent->len) && match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) string_list_insert(&s->ignored, ent->name); free(ent); } free(dir.entries); free(dir.ignored); clear_directory(&dir); if (advice_status_u_option) { struct timeval t_end; gettimeofday(&t_end, NULL); s->untracked_in_ms = (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 - ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000); } }
static int check_ignore(const char *prefix, const char **pathspec) { struct dir_struct dir; const char *path, *full_path; char *seen; int num_ignored = 0, dtype = DT_UNKNOWN, i; struct exclude *exclude; /* read_cache() is only necessary so we can watch out for submodules. */ if (read_cache() < 0) die(_("index file corrupt")); memset(&dir, 0, sizeof(dir)); setup_standard_excludes(&dir); if (!pathspec || !*pathspec) { if (!quiet) fprintf(stderr, "no pathspec given.\n"); return 0; } /* * look for pathspecs matching entries in the index, since these * should not be ignored, in order to be consistent with * 'git status', 'git add' etc. */ seen = find_pathspecs_matching_against_index(pathspec); for (i = 0; pathspec[i]; i++) { path = pathspec[i]; full_path = prefix_path(prefix, prefix ? strlen(prefix) : 0, path); full_path = check_path_for_gitlink(full_path); die_if_path_beyond_symlink(full_path, prefix); if (!seen[i]) { exclude = last_exclude_matching(&dir, full_path, &dtype); if (exclude) { if (!quiet) output_exclude(path, exclude); num_ignored++; } } } free(seen); clear_directory(&dir); return num_ignored; }
static void wt_status_collect_untracked(struct wt_status *s) { int i; struct dir_struct dir; uint64_t t_begin = getnanotime(); if (!s->show_untracked_files) return; memset(&dir, 0, sizeof(dir)); if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES) dir.flags |= DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; if (s->show_ignored_files) dir.flags |= DIR_SHOW_IGNORED_TOO; else dir.untracked = the_index.untracked; setup_standard_excludes(&dir); fill_directory(&dir, &s->pathspec); for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; if (cache_name_is_other(ent->name, ent->len) && dir_path_match(ent, &s->pathspec, 0, NULL)) string_list_insert(&s->untracked, ent->name); free(ent); } for (i = 0; i < dir.ignored_nr; i++) { struct dir_entry *ent = dir.ignored[i]; if (cache_name_is_other(ent->name, ent->len) && dir_path_match(ent, &s->pathspec, 0, NULL)) string_list_insert(&s->ignored, ent->name); free(ent); } free(dir.entries); free(dir.ignored); clear_directory(&dir); if (advice_status_u_option) s->untracked_in_ms = (getnanotime() - t_begin) / 1000000; }
static void read_directory(void) { struct stat st; clear_directory(); if (stat(inst_cwd, &st) < 0) directory_mtime = 0; else directory_mtime = st.st_mtime; /* if the stat call failed, this will probably break as well, but at the very least, it'll add an entry for the root directory. */ if (dmoz_read(inst_cwd, &flist, NULL, dmoz_read_instrument_library) < 0) log_perror(inst_cwd); dmoz_filter_filelist(&flist,instgrep, ¤t_file, file_list_reposition); dmoz_cache_lookup(inst_cwd, &flist, NULL); file_list_reposition(); }
static int clear_directory(char *dirname) { struct dirent *diriter; char fn[PATH_MAX]; DIR * dir; vv_printf("dirname %s\n", dirname); dir = opendir(dirname); if (dir == NULL) { v_printf("FAIL: dir is NULL %d %s\n", errno, strerror(errno)); return -1; } diriter = readdir(dir); if (diriter == NULL) { v_printf("FAIL: diriter is NULL %d %s\n", errno, strerror(errno)); } while (diriter != NULL) { struct stat stbuf; vv_printf("d_name %s\n", diriter->d_name); if (!strcmp(diriter->d_name, ".") || !strcmp(diriter->d_name, "..")) { vv_printf("ignoring . and ..\n"); diriter = readdir(dir); continue; } snprintf(fn, PATH_MAX , "%s/%s", dirname, diriter->d_name) ; if (S_ISDIR(stbuf.st_mode)) { vv_printf("directory: %s\n", fn); clear_directory(fn); } else { remove(fn); } diriter = readdir(dir); } closedir(dir); return 0; }
static int check_style_only( const struct section_global_data *global, struct compile_request_packet *req, struct compile_reply_packet *rpl, const unsigned char *pkt_name, const unsigned char *run_name, const unsigned char *work_run_name, const unsigned char *report_dir, const unsigned char *status_dir) { void *reply_bin = 0; size_t reply_bin_size = 0; unsigned char msgbuf[1024] = { 0 }; path_t log_path; path_t txt_path; path_t work_src_path; path_t work_log_path; int r, i; const unsigned char *src_sfx = ""; tpTask tsk = 0; // input file: ${global->compile_src_dir}/${pkt_name}${req->src_sfx} // output log file: ${report_dir}/${run_name} // file listing: ${report_dir}/${run_name} (if OK status) // working directory: ${global->compile_work_dir} snprintf(log_path, sizeof(log_path), "%s/%s", report_dir, run_name); snprintf(txt_path, sizeof(txt_path), "%s/%s.txt", report_dir, run_name); if (req->src_sfx) src_sfx = req->src_sfx; snprintf(work_src_path, sizeof(work_src_path), "%s/%s%s", global->compile_work_dir, work_run_name, src_sfx); snprintf(work_log_path, sizeof(work_log_path), "%s/%s.log", global->compile_work_dir, work_run_name); r = generic_copy_file(REMOVE, global->compile_src_dir, pkt_name, src_sfx, 0, global->compile_work_dir, work_run_name, src_sfx); if (!r) { snprintf(msgbuf, sizeof(msgbuf), "The source file %s/%s%s is missing.\n", global->compile_src_dir, pkt_name, src_sfx); goto internal_error; } if (r < 0) { snprintf(msgbuf, sizeof(msgbuf), "Read error on the source file %s/%s%s is missing.\n", global->compile_src_dir, pkt_name, src_sfx); goto internal_error; } //info("Starting: %s %s", req->style_checker, work_src_path); tsk = task_New(); task_AddArg(tsk, req->style_checker); task_AddArg(tsk, work_src_path); task_SetPathAsArg0(tsk); task_SetWorkingDir(tsk, global->compile_work_dir); task_EnableProcessGroup(tsk); task_SetRedir(tsk, 0, TSR_FILE, "/dev/null", TSK_READ); task_SetRedir(tsk, 1, TSR_FILE, work_log_path, TSK_REWRITE, 0777); task_SetRedir(tsk, 2, TSR_DUP, 1); if (req->sc_env_num > 0) { for (i = 0; i < req->sc_env_num; i++) task_PutEnv(tsk, req->sc_env_vars[i]); } task_EnableAllSignals(tsk); task_PrintArgs(tsk); if (task_Start(tsk) < 0) { err("Failed to start style checker process"); snprintf(msgbuf, sizeof(msgbuf), "Failed to start style checker %s\n", req->style_checker); goto internal_error; } task_Wait(tsk); if (task_IsTimeout(tsk)) { err("Style checker process is timed out"); snprintf(msgbuf, sizeof(msgbuf), "Style checker %s process timeout\n", req->style_checker); goto internal_error; } r = task_Status(tsk); if (r != TSK_EXITED && r != TSK_SIGNALED) { err("Style checker invalid task status"); snprintf(msgbuf, sizeof(msgbuf), "Style checker %s invalid task status %d\n", req->style_checker, r); goto internal_error; } if (r == TSK_SIGNALED) { err("Style checker terminated by signal"); snprintf(msgbuf, sizeof(msgbuf), "Style checker %s terminated by signal %d\n", req->style_checker, task_TermSignal(tsk)); goto internal_error; } r = task_ExitCode(tsk); if (r != 0 && r != RUN_COMPILE_ERR && r != RUN_PRESENTATION_ERR && r != RUN_WRONG_ANSWER_ERR && r != RUN_STYLE_ERR) { err("Invalid style checker exit code"); snprintf(msgbuf, sizeof(msgbuf), "Style checker %s exit code %d\n", req->style_checker, r); goto internal_error; } if (r) { // style checker error rpl->status = RUN_STYLE_ERR; get_current_time(&rpl->ts3, &rpl->ts3_us); generic_copy_file(0, 0, work_log_path, "", 0, 0, log_path, ""); generic_copy_file(0, 0, work_log_path, "", 0, 0, txt_path, ""); } else { // success rpl->status = RUN_OK; get_current_time(&rpl->ts3, &rpl->ts3_us); generic_copy_file(0, 0, work_log_path, "", 0, 0, txt_path, ""); } if (compile_reply_packet_write(rpl, &reply_bin_size, &reply_bin) < 0) goto cleanup; // ignore error: we cannot do anything anyway generic_write_file(reply_bin, reply_bin_size, SAFE, status_dir, run_name, 0); cleanup: task_Delete(tsk); tsk = 0; xfree(reply_bin); reply_bin = 0; req = compile_request_packet_free(req); clear_directory(global->compile_work_dir); return 0; internal_error: rpl->status = RUN_CHECK_FAILED; get_current_time(&rpl->ts3, &rpl->ts3_us); if (compile_reply_packet_write(rpl, &reply_bin_size, &reply_bin) < 0) goto cleanup; if (generic_write_file(msgbuf, strlen(msgbuf), 0, 0, log_path, 0) < 0) goto cleanup; if (generic_write_file(reply_bin, reply_bin_size, SAFE, status_dir, run_name, 0) < 0) { unlink(log_path); } goto cleanup; }
static int do_loop(void) { path_t src_name; path_t exe_name; path_t src_path; path_t exe_path; path_t log_path; path_t exe_out; path_t log_out; path_t txt_out; path_t report_dir, status_dir; path_t pkt_name, run_name, work_run_name; char *pkt_ptr; size_t pkt_len; int r, i; tpTask tsk = 0; unsigned char msgbuf[512]; int ce_flag; struct compile_request_packet *req = 0; struct compile_reply_packet rpl; void *rpl_pkt = 0; size_t rpl_size = 0; const unsigned char *tail_message = 0; #if HAVE_TRUNCATE - 0 struct stat stb; #endif /* HAVE_TRUNCATE */ FILE *log_f = 0; struct section_language_data *lang = 0; const struct section_global_data *global = serve_state.global; // if (cr_serialize_init(&serve_state) < 0) return -1; interrupt_init(); interrupt_disable(); while (1) { // terminate if signaled if (interrupt_get_status() || interrupt_restart_requested()) break; r = scan_dir(global->compile_queue_dir, pkt_name, sizeof(pkt_name)); if (r < 0) { switch (-r) { case ENOMEM: case ENOENT: case ENFILE: err("trying to recover, sleep for 5 seconds"); interrupt_enable(); os_Sleep(5000); interrupt_disable(); continue; default: err("unrecoverable error, exiting"); return -1; } } if (!r) { interrupt_enable(); os_Sleep(global->sleep_time); interrupt_disable(); continue; } pkt_ptr = 0; pkt_len = 0; r = generic_read_file(&pkt_ptr, 0, &pkt_len, SAFE | REMOVE, global->compile_queue_dir, pkt_name, ""); if (r == 0) continue; if (r < 0 || !pkt_ptr) { // it looks like there's no reasonable recovery strategy // so, just ignore the error continue; } r = compile_request_packet_read(pkt_len, pkt_ptr, &req); xfree(pkt_ptr); pkt_ptr = 0; if (r < 0) { /* * the incoming packet is completely broken, so just drop it */ goto cleanup_and_continue; } if (!req->contest_id) { // special packets r = req->lang_id; req = compile_request_packet_free(req); switch (r) { case 1: interrupt_flag_interrupt(); break; case 2: interrupt_flag_sighup(); break; } continue; } memset(&rpl, 0, sizeof(rpl)); rpl.judge_id = req->judge_id; rpl.contest_id = req->contest_id; rpl.run_id = req->run_id; rpl.ts1 = req->ts1; rpl.ts1_us = req->ts1_us; rpl.use_uuid = req->use_uuid; rpl.uuid[0] = req->uuid[0]; rpl.uuid[1] = req->uuid[1]; rpl.uuid[2] = req->uuid[2]; rpl.uuid[3] = req->uuid[3]; get_current_time(&rpl.ts2, &rpl.ts2_us); rpl.run_block_len = req->run_block_len; rpl.run_block = req->run_block; /* !!! shares memory with req */ msgbuf[0] = 0; /* prepare paths useful to report messages to the serve */ snprintf(report_dir, sizeof(report_dir), "%s/%06d/report", global->compile_dir, rpl.contest_id); snprintf(status_dir, sizeof(status_dir), "%s/%06d/status", global->compile_dir, rpl.contest_id); if (req->use_uuid > 0) { snprintf(run_name, sizeof(run_name), "%s", ej_uuid_unparse(req->uuid, NULL)); } else { snprintf(run_name, sizeof(run_name), "%06d", rpl.run_id); } snprintf(work_run_name, sizeof(work_run_name), "%06d", rpl.run_id); pathmake(log_out, report_dir, "/", run_name, NULL); snprintf(txt_out, sizeof(txt_out), "%s/%s.txt", report_dir, run_name); make_all_dir(status_dir, 0777); make_dir(report_dir, 0777); if (!r) { /* * there is something wrong, but we have contest_id, judge_id * and run_id in place, so we can report an error back * to serve */ snprintf(msgbuf, sizeof(msgbuf), "invalid compile packet\n"); goto report_internal_error; } if (req->style_check_only && req->style_checker && req->style_checker[0]) { check_style_only(global, req, &rpl, pkt_name, run_name, work_run_name, report_dir, status_dir); req = 0; continue; } if (req->lang_id <= 0 || req->lang_id > serve_state.max_lang || !(lang = serve_state.langs[req->lang_id])) { snprintf(msgbuf, sizeof(msgbuf), "invalid lang_id %d\n", req->lang_id); goto report_internal_error; } pathmake(src_name, work_run_name, lang->src_sfx, NULL); pathmake(exe_name, work_run_name, lang->exe_sfx, NULL); pathmake(src_path, global->compile_work_dir, "/", src_name, NULL); pathmake(exe_path, global->compile_work_dir, "/", exe_name, NULL); pathmake(log_path, global->compile_work_dir, "/", "log", NULL); /* the resulting executable file */ snprintf(exe_out, sizeof(exe_out), "%s/%s%s", report_dir, run_name, lang->exe_sfx); /* move the source file into the working dir */ r = generic_copy_file(REMOVE, global->compile_src_dir, pkt_name, lang->src_sfx, 0, global->compile_work_dir, src_name, ""); if (!r) { snprintf(msgbuf, sizeof(msgbuf), "the source file is missing\n"); err("the source file is missing"); goto report_internal_error; } if (r < 0) { snprintf(msgbuf, sizeof(msgbuf), "error reading the source file\n"); err("cannot read the source file"); goto report_internal_error; } tail_message = 0; ce_flag = 0; if (req->output_only) { // copy src_path -> exe_path generic_copy_file(0, NULL, src_path, NULL, 0, NULL, exe_path, NULL); ce_flag = 0; rpl.status = RUN_OK; } else { if (req->style_checker) { /* run style checker */ //info("Starting: %s %s", req->style_checker, src_path); tsk = task_New(); task_AddArg(tsk, req->style_checker); task_AddArg(tsk, src_path); task_SetPathAsArg0(tsk); task_SetWorkingDir(tsk, global->compile_work_dir); task_EnableProcessGroup(tsk); task_SetRedir(tsk, 0, TSR_FILE, "/dev/null", TSK_READ); task_SetRedir(tsk, 1, TSR_FILE, log_path, TSK_REWRITE, 0777); task_SetRedir(tsk, 2, TSR_DUP, 1); if (req->sc_env_num > 0) { for (i = 0; i < req->sc_env_num; i++) task_PutEnv(tsk, req->sc_env_vars[i]); } if (lang->compile_real_time_limit > 0) { task_SetMaxRealTime(tsk, lang->compile_real_time_limit); } task_EnableAllSignals(tsk); task_PrintArgs(tsk); if (task_Start(tsk) < 0) { err("Failed to start style checker process"); tail_message = "\n\nFailed to start style checker"; ce_flag = 1; rpl.status = RUN_STYLE_ERR; } else { task_Wait(tsk); if (task_IsTimeout(tsk)) { err("Style checker process timed out"); tail_message = "\n\nStyle checker process timed out"; ce_flag = 1; rpl.status = RUN_STYLE_ERR; } else if (task_IsAbnormal(tsk)) { info("Style checker failed"); ce_flag = 1; rpl.status = RUN_STYLE_ERR; } else { info("Style checker sucessful"); ce_flag = 0; rpl.status = RUN_OK; } } task_Delete(tsk); tsk = 0; } if (!ce_flag) { //info("Starting: %s %s %s", lang->cmd, src_name, exe_name); tsk = task_New(); task_AddArg(tsk, lang->cmd); task_AddArg(tsk, src_name); task_AddArg(tsk, exe_name); task_SetPathAsArg0(tsk); task_EnableProcessGroup(tsk); if (((ssize_t) req->max_vm_size) > 0) { task_SetVMSize(tsk, req->max_vm_size); } else if (((ssize_t) lang->max_vm_size) > 0) { task_SetVMSize(tsk, lang->max_vm_size); } else if (((ssize_t) global->compile_max_vm_size) > 0) { task_SetVMSize(tsk, global->compile_max_vm_size); } if (((ssize_t) req->max_stack_size) > 0) { task_SetStackSize(tsk, req->max_stack_size); } else if (((ssize_t) lang->max_stack_size) > 0) { task_SetStackSize(tsk, lang->max_stack_size); } else if (((ssize_t) global->compile_max_stack_size) > 0) { task_SetStackSize(tsk, global->compile_max_stack_size); } if (((ssize_t) req->max_file_size) > 0) { task_SetMaxFileSize(tsk, req->max_file_size); } else if (((ssize_t) lang->max_file_size) > 0) { task_SetMaxFileSize(tsk, lang->max_file_size); } else if (((ssize_t) global->compile_max_file_size) > 0) { task_SetMaxFileSize(tsk, global->compile_max_file_size); } if (req->env_num > 0) { for (i = 0; i < req->env_num; i++) task_PutEnv(tsk, req->env_vars[i]); } task_SetWorkingDir(tsk, global->compile_work_dir); task_SetRedir(tsk, 0, TSR_FILE, "/dev/null", TSK_READ); task_SetRedir(tsk, 1, TSR_FILE, log_path, TSK_APPEND, 0777); task_SetRedir(tsk, 2, TSR_DUP, 1); if (lang->compile_real_time_limit > 0) { task_SetMaxRealTime(tsk, lang->compile_real_time_limit); } task_EnableAllSignals(tsk); /* if (cr_serialize_lock(&serve_state) < 0) { // FIXME: propose reasonable recovery? return -1; } */ task_PrintArgs(tsk); task_Start(tsk); task_Wait(tsk); /* if (cr_serialize_unlock(&serve_state) < 0) { // FIXME: propose reasonable recovery? return -1; } */ if (task_IsTimeout(tsk)) { err("Compilation process timed out"); tail_message = "\n\nCompilation process timed out"; ce_flag = 1; rpl.status = RUN_COMPILE_ERR; } else if (task_IsAbnormal(tsk)) { info("Compilation failed"); ce_flag = 1; rpl.status = RUN_COMPILE_ERR; } else { info("Compilation sucessful"); ce_flag = 0; rpl.status = RUN_OK; } } } get_current_time(&rpl.ts3, &rpl.ts3_us); if (compile_reply_packet_write(&rpl, &rpl_size, &rpl_pkt) < 0) goto cleanup_and_continue; while (1) { if (ce_flag) { #if HAVE_TRUNCATE - 0 // truncate log file at size 1MB if (stat(log_path, &stb) >= 0 && stb.st_size > MAX_LOG_SIZE) { truncate(log_path, MAX_LOG_SIZE); if ((log_f = fopen(log_path, "a"))) { fprintf(log_f, "\n\nCompilation log is truncated by ejudge!\n"); fclose(log_f); log_f = 0; } } #endif // append tail_message if (tail_message && (log_f = fopen(log_path, "a"))) { fprintf(log_f, "%s\n", tail_message); fclose(log_f); log_f = 0; } r = generic_copy_file(0, 0, log_path, "", 0, 0, log_out, ""); } else { r = generic_copy_file(0, 0, exe_path, "", 0, 0, exe_out, ""); generic_copy_file(0, 0, log_path, "", 0, 0, txt_out, ""); } if (r >= 0 && generic_write_file(rpl_pkt, rpl_size, SAFE, status_dir, run_name, "") >= 0) break; info("waiting 5 seconds hoping for things to change"); interrupt_enable(); os_Sleep(5000); interrupt_disable(); } goto cleanup_and_continue; report_internal_error:; rpl.status = RUN_CHECK_FAILED; get_current_time(&rpl.ts3, &rpl.ts3_us); if (compile_reply_packet_write(&rpl, &rpl_size, &rpl_pkt) < 0) goto cleanup_and_continue; if (generic_write_file(msgbuf, strlen(msgbuf), 0, 0, log_out, 0) < 0) goto cleanup_and_continue; if (generic_write_file(rpl_pkt, rpl_size, SAFE, status_dir, run_name, 0) < 0) unlink(log_out); goto cleanup_and_continue; cleanup_and_continue:; task_Delete(tsk); tsk = 0; clear_directory(global->compile_work_dir); xfree(rpl_pkt); rpl_pkt = 0; req = compile_request_packet_free(req); } /* while (1) */ return 0; }
/* Walk a path string, either changing directories or finding the right path If mode is WALK_CHDIR, the result of this function is entering into the new directory on success, or the old directory being returned on failure. If mode is WALK_OPEN, the result of this function is the directory remains unchanged and a pointer to the directory entry for the requested file or directory is returned. If it is a file, the directory entry for the file itself is returned. If it is a directory, the directory entry of the first file or directory inside that directory is returned. The type specifier allows a person to specify that only a directory or file should be returned. This works for WALK_OPEN only. */ static int recurse_path(const char * const path, int mode, directory_entry_t **dirent, int type) { int ret = DFS_ESUCCESS; char token[MAX_FILENAME_LEN+1]; char *cur_path = (char *)path; uint32_t dir_stack[MAX_DIRECTORY_DEPTH]; uint32_t dir_loc = directory_top; int last_type = TYPE_ANY; int ignore = 1; // Do not, by default, read again during the first while /* Save directory stack */ memcpy(dir_stack, directories, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH); /* Grab first token, make sure it isn't root */ cur_path = get_next_token(cur_path, token); if(strcmp(token, "/") == 0) { /* It is an absolute path */ clear_directory(); /* Ensure that we remember this as a directory */ last_type = TYPE_DIR; /* We need to read through the first while loop */ ignore = 0; } /* Loop through the rest */ while(cur_path || ignore) { /* Grab out the next token */ if(!ignore) { cur_path = get_next_token(cur_path, token); } ignore = 0; if( (token[0] == '/' || token[0] == '.') ) { if(token[1] == '.') pop_directory();/* Up one directory */ last_type = TYPE_DIR; } else { /* Find directory entry, push */ directory_entry_t *tmp_node = find_dirent(token, peek_directory()); if(tmp_node) { /* Grab node, make sure it is a directory, push subdirectory, try again! */ directory_entry_t node; grab_sector(tmp_node, &node); uint32_t flags = get_flags(&node); if(FILETYPE(flags) == FLAGS_DIR) { /* Push subdirectory onto stack and loop */ push_directory(get_first_entry(&node)); last_type = TYPE_DIR; } else { if(mode == WALK_CHDIR) { /* Not found, this is a file */ ret = DFS_ENOFILE; break; } else { last_type = TYPE_FILE; /* Only count if this is the last thing we are doing */ if(!cur_path) { /* Push file entry onto stack in preparation of a return */ push_directory(tmp_node); } else { /* Not found, this is a file */ ret = DFS_ENOFILE; break; } } } } else { /* Not found! */ ret = DFS_ENOFILE; break; } } } if(type != TYPE_ANY && type != last_type) { /* Found an entry, but it was the wrong type! */ ret = DFS_ENOFILE; } if(mode == WALK_OPEN) { /* Must return the node found if we found one */ if(ret == DFS_ESUCCESS && dirent) { *dirent = peek_directory(); } } if(mode == WALK_OPEN || ret != DFS_ESUCCESS) { /* Restore stack */ directory_top = dir_loc; memcpy(directories, dir_stack, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH); } return ret; }
int main(int argc, char *argv[]) { char dirname[] = "one-open-many-writes"; char failedfiles[FHFMAX][FHFSIZE]; // Max files 256 (more than 16 segv's anyway); max filename size 64 (actually 19) int ret; int opt; int num_files = 1; // default for unit test int dirsread = 0; int filesread = 0; int errors = 0; int results[ResultSize]; bool fail = false; while ((opt = getopt (argc, argv, "uvwhf:")) != -1) { switch (opt) { case 'v': verbose = true; break; case 'w': vverbose = true; break; case 'f': num_files = strtol(optarg, NULL, 10); break; case 'h': case '?': default: usage (); } } for (int idx = 0; idx < ResultSize; idx++) { results[idx] = 0; } // An empty string ("") is the sentinel for (int idx = 0; idx < FHFMAX; idx++) { failedfiles[idx][0] = '\0'; } /* if (check_filesizes(dirname, true, results) < 0) { if (errno != ENOENT) { printf("FAIL: Couldn't delete directory contents\n"); exit(1); } } */ if (clear_directory(dirname) < 0) { if (errno != ENOENT) { printf("FAIL: Couldn't delete directory contents\n"); exit(1); } } if (remove(dirname) < 0) { if (errno != ENOENT) { printf("FAIL: Couldn't delete directory \'%s\'\n", dirname); exit(1); } } ret = mkdir(dirname, 0755); if (ret < 0) { printf("FAIL: Couldn't make directory %s. Exiting\n", dirname); exit(1); } ret = chdir(dirname); if (ret < 0) { printf("FAIL: Couldn't change to directory %s. Exiting\n", dirname); exit(1); } if (writeread(dirname, results, num_files, failedfiles) < 0) { // dirname is, oddly enough, the base name of the file printf("FAIL: writeread.\n"); fail = true; } /* if (check_filesizes(".", false, results) < 0) { v_printf("FAIL: check_filesizes.\n"); fail = true; } */ /* if (check_continualwrites_dir(".", results, failedfiles) < 0) { v_printf("FAIL: check_continualwrites_dir.\n"); fail = true; } */ for (int idx = 0; failedfiles[idx][0] != '\0'; idx++) { vv_printf("%s\n", failedfiles[idx]); } /* // hard-coding the path is not pretty, but it is clear ... // We did a chdir to continualwrites, hence the need to ../.. ret = chdir("../../cache/forensic-haven"); if (ret < 0) { printf("FAIL: Couldn't change to directory %s. Exiting\n", dirname); exit(1); } if (check_forensic_haven(".", results, failedfiles) < 0) { printf("FAIL: check_forensic_haven.\n"); } */ /* if (results[FilesizeErrors] > 0 || results[StatErrors] > 0 || results[OpenErrors] > 0 || results[FHOpenErrors] > 0 || results[FHReadErrors] > 0 || results[FHMissingErrors] > 0 || results[CWOpenErrors] > 0) { fail = true; } if (fail) { printf("FAIL: writes %d correct size %d dir reads %d fh found %d " "write errors %d filesize errors %d stat errors %d open errors %d " "fh open errors %d fh read errors %d fh missing errors %d\n", results[Writes], results[CorrectSize], results[DirReads], results[FHFound], results[WriteErrors], results[FilesizeErrors], results[StatErrors], results[OpenErrors], results[FHOpenErrors], results[FHReadErrors], results[FHMissingErrors], results[CWOpenErrors]); } else { printf("PASS: writes %d correct size %d dir reads %d fh found %d\n", results[Writes], results[CorrectSize], results[DirReads], results[FHFound]); } */ }
static int do_loop(void) { int r; path_t report_path; path_t full_report_path; path_t pkt_name; unsigned char exe_pkt_name[64]; unsigned char run_base[64]; path_t full_report_dir; path_t full_status_dir; path_t full_full_dir; char exe_name[64]; int tester_id; struct section_tester_data tn, *tst; int got_quit_packet = 0; struct run_reply_packet reply_pkt; void *reply_pkt_buf = 0; size_t reply_pkt_buf_size = 0; unsigned char errmsg[512]; const struct section_global_data *global = serve_state.global; const unsigned char *arch = 0; char *srp_b = 0; size_t srp_z = 0; struct super_run_in_packet *srp = NULL; struct super_run_in_global_packet *srgp = NULL; struct super_run_in_problem_packet *srpp = NULL; memset(&tn, 0, sizeof(tn)); //if (cr_serialize_init(&serve_state) < 0) return -1; interrupt_init(); interrupt_disable(); while (1) { interrupt_enable(); /* time window for immediate signal delivery */ interrupt_disable(); // terminate, if signaled if (interrupt_get_status()) break; if (interrupt_restart_requested()) { restart_flag = 1; } if (restart_flag) break; r = scan_dir(global->run_queue_dir, pkt_name, sizeof(pkt_name)); if (r < 0) return -1; if (!r) { if (got_quit_packet && managed_mode_flag) { return 0; } if (managed_mode_flag && global->inactivity_timeout > 0 && last_activity_time + global->inactivity_timeout < time(0)) { info("no activity for %d seconds, exiting",global->inactivity_timeout); return 0; } interrupt_enable(); os_Sleep(global->sleep_time); interrupt_disable(); continue; } last_activity_time = time(0); srp = super_run_in_packet_free(srp); xfree(srp_b); srp_b = NULL; srp_z = 0; r = generic_read_file(&srp_b, 0, &srp_z, SAFE | REMOVE, global->run_queue_dir, pkt_name, ""); if (r == 0) continue; if (r < 0) return -1; if (!strcmp(pkt_name, "QUIT")) { if (managed_mode_flag) { got_quit_packet = 1; info("got force quit run packet"); } else { restart_flag = 1; } xfree(srp_b); srp_b = NULL; srp_z = 0; continue; } fprintf(stderr, "packet: <<%.*s>>\n", (int) srp_z, srp_b); srp = super_run_in_packet_parse_cfg_str(pkt_name, srp_b, srp_z); //xfree(srp_b); srp_b = NULL; srp_z = 0; if (!srp) { err("failed to parse file %s", pkt_name); continue; } if (!(srgp = srp->global)) { err("packet %s has no global section", pkt_name); continue; } if (srgp->contest_id <= 0) { err("packet %s: undefined contest_id", pkt_name); continue; } if (managed_mode_flag && srgp->restart > 0) { got_quit_packet = 1; info("got force quit run packet"); continue; } if (srgp->restart > 0) { restart_flag = 1; continue; } /* if (req_pkt->contest_id == -1) { r = generic_write_file(req_buf, req_buf_size, SAFE, serve_state.global->run_queue_dir, pkt_name, ""); if (r < 0) return -1; info("force quit packet is ignored in unmanaged mode"); scan_dir_add_ignored(serve_state.global->run_queue_dir, pkt_name); continue; } */ if (!(srpp = srp->problem)) { err("packet %s: no [problem] section", pkt_name); continue; } /* if we are asked to do full testing, but don't want */ if ((global->skip_full_testing > 0 && !srgp->accepting_mode) || (global->skip_accept_testing > 0 && srgp->accepting_mode)) { r = generic_write_file(srp_b, srp_z, SAFE, global->run_queue_dir, pkt_name, ""); if (r < 0) return -1; info("skipping problem %s", srpp->short_name); scan_dir_add_ignored(global->run_queue_dir, pkt_name); continue; } /* if this problem is marked as "skip_testing" put the * packet back to the spool directory */ #if 0 if (cur_prob->skip_testing > 0) { r = generic_write_file(srp_b, srp_z, SAFE, global->run_queue_dir, pkt_name, ""); if (r < 0) return -1; info("skipping problem %s", cur_prob->short_name); scan_dir_add_ignored(global->run_queue_dir, pkt_name); continue; } #endif snprintf(run_base, sizeof(run_base), "%06d", srgp->run_id); report_path[0] = 0; full_report_path[0] = 0; if (srpp->type_val == PROB_TYPE_TESTS) { //cr_serialize_lock(&serve_state); run_inverse_testing(&serve_state, srp, &reply_pkt, pkt_name, global->run_exe_dir, report_path, sizeof(report_path), utf8_mode); //cr_serialize_unlock(&serve_state); } else { arch = srgp->arch; if (!arch) arch = ""; if (srpp->type_val > 0 && arch && !*arch) { // any tester will work for output-only problems arch = 0; } /* regular problem */ if (!(tester_id = find_tester(&serve_state, srpp->id, arch))){ snprintf(errmsg, sizeof(errmsg), "no tester found for %d, %s\n", srpp->id, srgp->arch); goto report_check_failed_and_continue; } info("fount tester %d for pair %d,%s", tester_id, srpp->id, srgp->arch); tst = serve_state.testers[tester_id]; if (tst->any) { info("tester %d is a default tester", tester_id); r = prepare_tester_refinement(&serve_state, &tn, tester_id, srpp->id); ASSERT(r >= 0); tst = &tn; } /* if this tester is marked as "skip_testing" put the * packet back to the spool directory */ if (tst->skip_testing > 0) { r = generic_write_file(srp_b, srp_z, SAFE, global->run_queue_dir, pkt_name, ""); if (r < 0) return -1; info("skipping tester <%s,%s>", srpp->short_name, tst->arch); scan_dir_add_ignored(global->run_queue_dir, pkt_name); if (tst == &tn) { sarray_free(tst->start_env); tst->start_env = 0; sarray_free(tst->super); tst->super = 0; } continue; } snprintf(exe_pkt_name, sizeof(exe_pkt_name), "%s%s", pkt_name, srgp->exe_sfx); snprintf(exe_name, sizeof(exe_name), "%s%s", run_base, srgp->exe_sfx); r = generic_copy_file(REMOVE, global->run_exe_dir, exe_pkt_name, "", 0, global->run_work_dir, exe_name, ""); if (r <= 0) { snprintf(errmsg, sizeof(errmsg), "failed to copy executable file %s/%s\n", global->run_exe_dir, exe_pkt_name); goto report_check_failed_and_continue; } /* start filling run_reply_packet */ memset(&reply_pkt, 0, sizeof(reply_pkt)); reply_pkt.judge_id = srgp->judge_id; reply_pkt.contest_id = srgp->contest_id; reply_pkt.run_id = srgp->run_id; reply_pkt.notify_flag = srgp->notify_flag; reply_pkt.user_status = -1; reply_pkt.user_tests_passed = -1; reply_pkt.user_score = -1; reply_pkt.ts1 = srgp->ts1; reply_pkt.ts1_us = srgp->ts1_us; reply_pkt.ts2 = srgp->ts2; reply_pkt.ts2_us = srgp->ts2_us; reply_pkt.ts3 = srgp->ts3; reply_pkt.ts3_us = srgp->ts3_us; reply_pkt.ts4 = srgp->ts4; reply_pkt.ts4_us = srgp->ts4_us; get_current_time(&reply_pkt.ts5, &reply_pkt.ts5_us); //if (cr_serialize_lock(&serve_state) < 0) return -1; run_tests(ejudge_config, &serve_state, tst, srp, &reply_pkt, srgp->accepting_mode, srpp->accept_partial, srgp->variant, exe_name, run_base, report_path, full_report_path, srgp->user_spelling, srpp->spelling, NULL /* mirror_dir */, utf8_mode); //if (cr_serialize_unlock(&serve_state) < 0) return -1; if (tst == &tn) { sarray_free(tst->start_env); tst->start_env = 0; sarray_free(tst->super); tst->super = 0; } } if (srgp->reply_report_dir && srgp->reply_report_dir[0]) { snprintf(full_report_dir, sizeof(full_report_dir), "%s", srgp->reply_report_dir); } else { snprintf(full_report_dir, sizeof(full_report_dir), "%s/%06d/report", global->run_dir, srgp->contest_id); } if (srgp->reply_spool_dir && srgp->reply_spool_dir[0]) { snprintf(full_status_dir, sizeof(full_status_dir), "%s", srgp->reply_spool_dir); } else { snprintf(full_status_dir, sizeof(full_status_dir), "%s/%06d/status", global->run_dir, srgp->contest_id); } if (srgp->reply_full_archive_dir && srgp->reply_full_archive_dir[0]) { snprintf(full_full_dir, sizeof(full_full_dir), "%s", srgp->reply_full_archive_dir); } else { snprintf(full_full_dir, sizeof(full_full_dir), "%s/%06d/output", global->run_dir, srgp->contest_id); } if (generic_copy_file(0, NULL, report_path, "", 0, full_report_dir, run_base, "") < 0) return -1; #if defined CONF_HAS_LIBZIP if (full_report_path[0] && generic_copy_file(0, NULL, full_report_path, "", 0, full_full_dir, run_base, ".zip") < 0) return -1; #else if (full_report_path[0] && generic_copy_file(0, NULL, full_report_path, "", 0, full_full_dir, run_base, "") < 0) return -1; #endif //run_reply_packet_dump(&reply_pkt); if (run_reply_packet_write(&reply_pkt, &reply_pkt_buf_size, &reply_pkt_buf) < 0) { /* FIXME: do something, if this is possible. * However, unability to generate a reply packet only * means that invalid data passed, which should be reported * immediately as internal error! */ abort(); } if (generic_write_file(reply_pkt_buf, reply_pkt_buf_size, SAFE, full_status_dir, run_base, "") < 0) { xfree(reply_pkt_buf); reply_pkt_buf = 0; return -1; } xfree(reply_pkt_buf); reply_pkt_buf = 0; clear_directory(global->run_work_dir); last_activity_time = time(0); continue; report_check_failed_and_continue:; memset(&reply_pkt, 0, sizeof(reply_pkt)); reply_pkt.judge_id = srgp->judge_id; reply_pkt.contest_id = srgp->contest_id; reply_pkt.run_id = srgp->run_id; reply_pkt.user_status = -1; reply_pkt.user_tests_passed = -1; reply_pkt.user_score = -1; reply_pkt.ts1 = srgp->ts1; reply_pkt.ts1_us = srgp->ts1_us; reply_pkt.ts2 = srgp->ts2; reply_pkt.ts2_us = srgp->ts2_us; reply_pkt.ts3 = srgp->ts3; reply_pkt.ts3_us = srgp->ts3_us; reply_pkt.ts4 = srgp->ts4; reply_pkt.ts4_us = srgp->ts4_us; get_current_time(&reply_pkt.ts5, &reply_pkt.ts5_us); reply_pkt.ts6 = reply_pkt.ts5; reply_pkt.ts6_us = reply_pkt.ts5_us; reply_pkt.ts7 = reply_pkt.ts5; reply_pkt.ts7_us = reply_pkt.ts5_us; reply_pkt.status = RUN_CHECK_FAILED; reply_pkt.failed_test = 0; reply_pkt.score = -1; if (run_reply_packet_write(&reply_pkt, &reply_pkt_buf_size, &reply_pkt_buf) < 0) { // oops :( abort(); } if (generic_write_file(errmsg, strlen(errmsg), 0, full_report_dir, run_base, "") < 0 || generic_write_file(reply_pkt_buf, reply_pkt_buf_size, SAFE, full_status_dir, run_base, "") < 0) { err("error writing check failed packet"); } clear_directory(global->run_work_dir); } srp = super_run_in_packet_free(srp); xfree(srp_b); srp_b = NULL; srp_z = 0; return 0; }