int taskq_main(int argc,char **argv) { putenv("PATH=/bin:/service/tools:/service/init"); signal(SIGINT, exit_program); signal(SIGTERM, exit_program); signal(SIGHUP, exit_program); signal(SIGKILL, exit_program); freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); strcpy(argv[0],"taskq "); chdir("/"); if(daemon(1,1)==0) { for(;;) { listcnt=read_config(); if(listcnt!=0) { run_list(); free_list(); } sleep(1); } } exit(0); }
void eval_line(const char* s) { int type; char* token; // Your code here! // build the command command* c = command_alloc(); while ((s = parse_shell_token(s, &type, &token)) != NULL) command_append_arg(c, token); // execute it if (c->argc) run_list(c); command_free(c); }
/// Lists the test cases in a test program. /// /// \param test_program Path to the test program for which to list the test /// cases. Should be absolute. /// \param run_params Execution parameters to configure the test process. /// /// \return An error if the listing fails; OK otherwise. static kyua_error_t list_test_cases(const char* test_program, const kyua_run_params_t* run_params) { kyua_error_t error; char* work_directory; error = kyua_run_work_directory_enter(WORKDIR_TEMPLATE, run_params->unprivileged_user, run_params->unprivileged_group, &work_directory); if (kyua_error_is_set(error)) goto out; kyua_run_params_t real_run_params = *run_params; real_run_params.work_directory = work_directory; int stdout_fds[2]; if (pipe(stdout_fds) == -1) { error = kyua_libc_error_new(errno, "pipe failed"); goto out_work_directory; } pid_t pid; error = kyua_run_fork(&real_run_params, &pid); if (!kyua_error_is_set(error) && pid == 0) { run_list(test_program, stdout_fds); } assert(pid != -1 && pid != 0); if (kyua_error_is_set(error)) goto out_stdout_fds; FILE* tmp_output = NULL; // Initialize to shut up gcc warning. error = create_file_in_work_directory(real_run_params.work_directory, "list.txt", "w+", &tmp_output); if (kyua_error_is_set(error)) goto out_stdout_fds; close(stdout_fds[1]); stdout_fds[1] = -1; kyua_error_t parse_error = atf_list_parse(stdout_fds[0], tmp_output); stdout_fds[0] = -1; // Guaranteed closed by atf_list_parse. // Delay reporting of parse errors to later. If we detect a problem while // waiting for the test program, we know that the parsing has most likely // failed and therefore the error with the program is more important for // reporting purposes. int status; bool timed_out; error = kyua_run_wait(pid, &status, &timed_out); if (kyua_error_is_set(error)) goto out_tmp_output; if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { error = kyua_generic_error_new("Test program list did not return " "success"); goto out_tmp_output; } error = kyua_error_subsume(error, parse_error); if (!kyua_error_is_set(error)) { rewind(tmp_output); error = dump_file(tmp_output, stdout); } out_tmp_output: fclose(tmp_output); out_stdout_fds: if (stdout_fds[0] != -1) close(stdout_fds[0]); if (stdout_fds[1] != -1) close(stdout_fds[1]); out_work_directory: error = kyua_error_subsume(error, kyua_run_work_directory_leave(&work_directory)); out: return error; }
static int run_action_server_do(struct async *as, struct sdirs *sdirs, const char *incexc, int srestore, int *timer_ret, struct conf **cconfs) { int ret; int resume=0; char msg[256]=""; struct iobuf *rbuf=as->asfd->rbuf; // Make sure some directories exist. if(mkpath(&sdirs->current, sdirs->dedup)) { snprintf(msg, sizeof(msg), "could not mkpath %s", sdirs->current); log_and_send(as->asfd, msg); return -1; } if(rbuf->cmd!=CMD_GEN) return unknown_command(as->asfd); // List and diff should work even while backups are running. if(!strncmp_w(rbuf->buf, "list ") || !strncmp_w(rbuf->buf, "listb ")) return run_list(as->asfd, sdirs, cconfs); if(!strncmp_w(rbuf->buf, "diff ")) return run_diff(as->asfd, sdirs, cconfs); switch((ret=get_lock_sdirs(as->asfd, sdirs))) { case 0: break; // OK. case 1: return 1; // Locked out. default: // Error. maybe_do_notification(as->asfd, ret, "", "error in get_lock_sdirs()", "", buf_to_notify_str(rbuf), cconfs); return -1; } switch((ret=check_for_rubble(as, sdirs, incexc, &resume, cconfs))) { case 0: break; // OK. case 1: return 1; // Now finalising. default: // Error. maybe_do_notification(as->asfd, ret, "", "error in check_for_rubble()", "", buf_to_notify_str(rbuf), cconfs); return -1; } if(!strncmp_w(rbuf->buf, "backup")) { ret=run_backup(as, sdirs, cconfs, incexc, timer_ret, resume); if(*timer_ret<0) maybe_do_notification(as->asfd, ret, "", "error running timer script", "", "backup", cconfs); else if(!*timer_ret) maybe_do_notification(as->asfd, ret, sdirs->client, sdirs->current, "log", "backup", cconfs); return ret; } if(!strncmp_w(rbuf->buf, "restore ") || !strncmp_w(rbuf->buf, "verify ")) return run_restore(as->asfd, sdirs, cconfs, srestore); if(!strncmp_w(rbuf->buf, "Delete ")) return run_delete(as->asfd, sdirs, cconfs); // Old clients will send 'delete', possibly accidentally due to the // user trying to use the new diff/long diff options. // Stop them from working, just to be safe. if(!strncmp_w(rbuf->buf, "delete ")) { logp("old style delete from %s denied\n", get_string(cconfs[OPT_CNAME])); as->asfd->write_str(as->asfd, CMD_ERROR, "old style delete is not supported on this server"); return -1; } return unknown_command(as->asfd); }