void tkit::proc_timer::run(bool should_wait) { std::vector<char*> cargs; for (int i = 0; i < _args.size(); i++) { const auto arg = _args[i]; cargs.push_back(const_cast<char*>(arg.c_str())); } cargs.push_back(nullptr); _id = fork(); if (_id == -1) throw fork_error(); itimerval time_limit, old; time_limit.it_value = {_lim / 1000, (_lim % 1000) * 1000}; time_limit.it_interval = {0, 0}; // Limits on the child process: const rlimit process_lim = {1, 1}; if (_id == 0) { setitimer(ITIMER_PROF, &time_limit, &old); setrlimit(RLIMIT_NPROC, &process_lim); execvp(_args[0].c_str(), cargs.data()); _exit(EXIT_FAILURE); } std::thread run_thread(&tkit::proc_timer::_run_helper, this); if (should_wait) run_thread.join(); else run_thread.detach(); }
void fork_proc (node_type *cur, int pfd) { pid_t par=getpid(); size_t i=0; pid_t ch[2]; int p[2][2]; int result=0, res[2]={0, 0}; int rwn=0, rwrv=0; if (!cur->nr_children) { //If no children: atoi arg. result=atoi(cur->name); } else if (cur->nr_children==2) { //Child with 2 children: Open pipes, fork children, and wait to read. for (i=0; i<cur->nr_children; i++) { //For the 2 children, open pipes, and fork giving them the write end. if (pipe(p[i])) { //Open pipe. pipe_error(par); shit_n_exit;//exit(EXIT_FAILURE); } ch[i]=fork(); //Fork. if (ch[i]<0) { fork_error(par); shit_n_exit;//exit(EXIT_FAILURE); } else if (ch[i]==0) { ccret(close(p[i][0])); fork_proc(&cur->children[i], p[i][1]); } else { ccret(close(p[i][1])); } } for (i=0; i<cur->nr_children; i++) { //Read from the 2 child streams (and bury them in the process). rwn=rwrv=0; while (rwn<sizeof(int)) { if ((rwrv=read(p[i][0], &res[i]+rwn, sizeof(int)-rwn))==-1) { read_err(par); shit_n_exit;//exit(EXIT_FAILURE); } rwn+=rwrv; } ccret(close(p[i][0])); wait(NULL); } _Bool err=0; result = (cur->name[0]=='+') ? res[0]+res[1] : ((cur->name[0]=='*') ? res[0]*res[1] : ((cur->name[0]=='-') ? res[0]-res[1] : (err=1))); if (err && op_err(par, cur->name[0]) && shit_n_exit) ; } else { //Child with illegal number of children: fprintf(stderr, "Illegal operand number ( %u ) in process: %ld.\n", cur->nr_children, (long)par); shit_n_exit;//exit(EXIT_FAILURE); } rwn=sizeof(int); printf("Writing data (%d) to pipe from process %ld.\n", result, (long)par); while (rwn!=0) { if ((rwrv=write(pfd, &result+sizeof(int)-rwn, (sizeof(int)<<1)-rwn))==-1) { write_err(par); shit_n_exit;//exit(EXIT_FAILURE); } rwn-=rwrv; } ccret(close(pfd)); exit(EXIT_SUCCESS); }