Beispiel #1
0
/* 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;
}
Beispiel #2
0
/*
 * `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;
}
Beispiel #5
0
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);
	}
}
Beispiel #6
0
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;
}
Beispiel #7
0
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, &current_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;
}
Beispiel #10
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;
}
Beispiel #11
0
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;
}
Beispiel #12
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]);
    }
    */
}
Beispiel #14
0
Datei: run.c Projekt: NUOG/ejudge
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;
}