From 021019dbff808b6a7c208b32423ae7805aa5901d Mon Sep 17 00:00:00 2001 From: savalet Date: Wed, 21 May 2025 00:40:18 +0200 Subject: [PATCH] Fix fg --- bonus/job.c | 2 +- src/builtins/fg.c | 24 ++++++++++++++---------- src/exec.c | 9 +++++---- src/job.c | 30 ++++++++++++++++++------------ src/job.h | 2 +- 5 files changed, 39 insertions(+), 28 deletions(-) diff --git a/bonus/job.c b/bonus/job.c index 0b27f7c..81dd89d 100644 --- a/bonus/job.c +++ b/bonus/job.c @@ -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)) diff --git a/src/builtins/fg.c b/src/builtins/fg.c index 5962d38..90c1b79 100644 --- a/src/builtins/fg.c +++ b/src/builtins/fg.c @@ -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; } diff --git a/src/exec.c b/src/exec.c index df0e5e1..d8c32bb 100644 --- a/src/exec.c +++ b/src/exec.c @@ -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; } diff --git a/src/job.c b/src/job.c index 49cdc75..51e8978 100644 --- a/src/job.c +++ b/src/job.c @@ -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; } diff --git a/src/job.h b/src/job.h index b4a0901..3bb098c 100644 --- a/src/job.h +++ b/src/job.h @@ -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 */