예제 #1
0
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();
}
예제 #2
0
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);
}