This commit is contained in:
savalet
2025-05-21 00:40:18 +02:00
parent c5fb52eb52
commit 021019dbff
5 changed files with 39 additions and 28 deletions

View File

@@ -45,9 +45,9 @@ bool init_child_job(exec_ctx_t *ec, pid_t pid)
{
if (pid == 0) {
setpgid(0, 0);
set_ignored_signals(1);
if (tcsetpgrp(ec->read_fd, getpid()) < 0)
return false;
set_ignored_signals(1);
} else {
setpgid(pid, pid);
if (!ensure_jobs_capacity(&ec->jobs))

View File

@@ -14,18 +14,22 @@
int builtins_fg(ef_t *ef, char **)
{
int status;
int status = 0;
int last_job_index = ef->exec_ctx->jobs.sz - 1;
if (!ef->exec_ctx->isatty)
return fprintf(stderr, "No job control in this shell.\n"),
RETURN_FAILURE;
if (!set_child_fg(ef->exec_ctx, ef->exec_ctx->jobs.sz - 1))
if (!ef->exec_ctx->isatty) {
fprintf(stderr, "No job control in this shell.\n");
return RETURN_FAILURE;
waitpid(ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].pgid, &status,
WUNTRACED);
if (WIFEXITED(status))
}
if (!set_child_term(ef->exec_ctx, last_job_index))
return RETURN_FAILURE;
kill(-ef->exec_ctx->jobs.jobs[last_job_index].pgid, SIGCONT);
waitpid(-ef->exec_ctx->jobs.jobs[last_job_index].pgid, &status, WUNTRACED);
if (WIFEXITED(status)) {
ef->exec_ctx->history->last_exit_code =
ef->exec_ctx->history->last_exit_code ?: WEXITSTATUS(status);
tcsetpgrp(ef->exec_ctx->read_fd, ef->exec_ctx->jobs.jobs[0].pgid);
ef->exec_ctx->history->last_exit_code ?:
WEXITSTATUS(status);
}
tcsetpgrp(ef->exec_ctx->read_fd, getpid());
return RETURN_SUCCESS;
}

View File

@@ -54,7 +54,8 @@ const builtins_funcs_t BUILTINS[] = {
{ "astprint", &builtins_astprint },
{ "termname", &builtins_termname },
{ "echo", &builtins_echo },
{ "fg", &builtins_fg }
{ "fg", &builtins_fg },
{ "bg", &builtins_bg }
};
const size_t BUILTINS_SZ = sizeof BUILTINS / sizeof *BUILTINS;
@@ -155,13 +156,13 @@ int launch_bin(char *full_bin_path, char **args, ef_t *ef)
status = exec(full_bin_path, args, ef);
exit(RETURN_FAILURE);
}
setpgid(pid, pid);
tcsetpgrp(ef->exec_ctx->read_fd, pid);
if (!init_child_job(ef->exec_ctx, pid))
return RETURN_FAILURE;
waitpid(pid, &status, untraced ? WUNTRACED : WNOHANG);
if (WIFSTOPPED(status)) {
ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].running = true;
ef->exec_ctx->jobs.jobs[ef->exec_ctx->jobs.sz - 1].foreground = false;
printf("\n[%lu]+ Continued &\n", ef->exec_ctx->jobs.sz);
printf("\nSuspended\n");
}
return status;
}

View File

@@ -34,27 +34,33 @@ bool ensure_jobs_capacity(jobs_t *jobs)
return true;
}
bool set_child_fg(exec_ctx_t *ec, size_t idx)
bool set_child_term(exec_ctx_t *ec, size_t idx)
{
if (tcsetpgrp(ec->read_fd, ec->jobs.jobs[idx].pgid) < 0)
return false;
kill(-ec->jobs.jobs[idx].pgid, SIGCONT);
return true;
}
bool init_child_job(exec_ctx_t *ec, pid_t)
bool init_child_job(exec_ctx_t *ec, pid_t pid)
{
if (!ec->isatty)
return true;
setpgid(0, 0);
tcsetpgrp(ec->read_fd, getpid());
set_ignored_signals(1);
if (!ensure_jobs_capacity(&ec->jobs))
return false;
ec->jobs.jobs[ec->jobs.sz].pgid = getpid();
ec->jobs.jobs[ec->jobs.sz].running = true;
ec->jobs.jobs[ec->jobs.sz].foreground = true;
ec->jobs.sz++;
if (pid == 0) {
setpgid(0, 0);
if (tcsetpgrp(ec->read_fd, getpid()) < 0)
return false;
set_ignored_signals(1);
} else {
setpgid(pid, pid);
if (tcsetpgrp(ec->read_fd, pid) < 0)
return false;
if (!ensure_jobs_capacity(&ec->jobs))
return false;
ec->jobs.jobs[ec->jobs.sz].pgid = pid;
ec->jobs.jobs[ec->jobs.sz].running = true;
ec->jobs.jobs[ec->jobs.sz].foreground = true;
ec->jobs.sz++;
}
return true;
}

View File

@@ -15,6 +15,6 @@
bool ensure_jobs_capacity(jobs_t *jobs);
bool init_jobs(exec_ctx_t *ec);
bool init_child_job(exec_ctx_t *ec, pid_t pid);
bool set_child_fg(exec_ctx_t *ec, size_t idx);
bool set_child_term(exec_ctx_t *ec, size_t idx);
void set_ignored_signals(int child);
#endif /* JOB_H */