~emersion/mrsh

ee80db4d9ac87dbb0eedc3a50ab7e5bafac6633d — Simon Ser 1 year, 1 month ago 18a516b
Introduce job_poll
2 files changed, 34 insertions(+), 3 deletions(-)

M include/shell/job.h
M shell/job.c
M include/shell/job.h => include/shell/job.h +7 -0
@@ 44,6 44,13 @@ bool job_terminated(struct mrsh_job *job);
 */
bool job_stopped(struct mrsh_job *job);
/**
 * Polls the job's current status without blocking. Returns:
 * - An integer >= 0 if the job has terminated
 * - TASK_STATUS_STOPPED if the job is stopped
 * - TASK_STATUS_WAIT if the job is running
 */
int job_poll(struct mrsh_job *job);
/**
 * Wait for the completion of the job.
 */
int job_wait(struct mrsh_job *job);

M shell/job.c => shell/job.c +27 -3
@@ 184,8 184,34 @@ bool job_set_foreground(struct mrsh_job *job, bool foreground, bool cont) {
	return true;
}

int job_poll(struct mrsh_job *job) {
	int proc_status = 0;
	bool stopped = false;
	for (size_t j = 0; j < job->processes.len; ++j) {
		struct process *proc = job->processes.data[j];
		proc_status = process_poll(proc);
		if (proc_status == TASK_STATUS_WAIT) {
			return TASK_STATUS_WAIT;
		}
		if (proc_status == TASK_STATUS_STOPPED) {
			stopped = true;
		}
	}

	if (stopped) {
		return TASK_STATUS_STOPPED;
	}
	// All processes have terminated, return the last one's status
	return proc_status;
}

int job_wait(struct mrsh_job *job) {
	while (!job_stopped(job) && !job_terminated(job)) {
	while (true) {
		int status = job_poll(job);
		if (status != TASK_STATUS_WAIT) {
			return status;
		}

		int stat;
		pid_t pid = waitpid(-1, &stat, WUNTRACED);
		if (pid == -1) {


@@ 198,8 224,6 @@ int job_wait(struct mrsh_job *job) {

		update_job(job->state, pid, stat);
	}

	return 0; // TODO: return the job's status
}

bool init_job_child_process(struct mrsh_state *state) {