aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-08-12 12:22:23 +0000
committer_ov4 <ov4@ov4.org>2026-08-12 12:22:23 +0000
commitc2d1c8f63504c5ca65c127d6dba4cd7e39399066 (patch)
treecb75abd2262dd7a4e0c8ff16231c5f57a33f303f
parent5182cddfc8e1f4c1ab80d90dedbf4fc95b71c3c2 (diff)
Forward SIGINT to foreground job.
-rw-r--r--tsh.cc45
1 files changed, 40 insertions, 5 deletions
diff --git a/tsh.cc b/tsh.cc
index 61537a3..f6027ae 100644
--- a/tsh.cc
+++ b/tsh.cc
@@ -85,6 +85,7 @@ struct job_t *getjobpid(struct job_t *jobs, pid_t pid);
struct job_t *getjobjid(struct job_t *jobs, int jid);
int pid2jid(pid_t pid);
void listjobs(struct job_t *jobs);
+bool job_suspend(struct job_t *jobs, pid_t pid);
void usage(void);
void unix_error(char *msg);
@@ -233,8 +234,7 @@ void eval(char *cmdline)
// unblock all expect SIGCHILD
sigprocmask(SIG_SETMASK, &prev_all, NULL);
// we still leave SIGCHLD to be unblocked within waitfg()
- // this pid is USELESS!!!
- waitfg(0);
+ waitfg(pid);
// and then unblock SIGCHLD
sigprocmask(SIG_SETMASK, &prev, NULL);
}
@@ -341,9 +341,14 @@ void waitfg(pid_t pid)
// remove SIGCHILD
sigdelset(&prev, SIGCHLD);
clog << "waiting for pid "<< fgpid(jobs) << endl;
+ job_t *j = getjobpid(jobs, pid);
while (fgpid(jobs) != 0)
sigsuspend(&prev);
- clog << "finished fg " << fgpid(jobs) << endl;
+ clog << "finished fg " << endl;
+ if ((j->state == ST))
+ {
+ cout << "[" << j->jid << "] (" << pid << ") Stopped " << j->cmdline << endl;
+ }
return;
}
@@ -362,11 +367,13 @@ void sigchld_handler(int sig)
{
int errno_backup = errno;
int status, pid;
- char msg[] = "sig chld, pid: ";
- write(STDOUT_FILENO, msg, strlen(msg));
+ atomic_print("SIGCHLD\n");
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
{
+ atomic_print("pid: ");
+ atomic_print(pid);
+ atomic_print("\n");
deletejob(jobs, pid);
atomic_print(pid);
}
@@ -383,6 +390,11 @@ void sigchld_handler(int sig)
*/
void sigint_handler(int sig)
{
+ int pid = fgpid(jobs);
+ if (pid != 0)
+ {
+ kill(-pid, SIGINT);
+ }
return;
}
@@ -393,6 +405,16 @@ void sigint_handler(int sig)
*/
void sigtstp_handler(int sig)
{
+ int pid = fgpid(jobs);
+ if (pid != 0)
+ {
+ kill(-pid, SIGTSTP);
+ sigset_t mask_all, prev;
+ sigfillset(&mask_all);
+ sigprocmask(SIG_SETMASK, &mask_all, &prev);
+ job_suspend(jobs, pid);
+ sigprocmask(SIG_SETMASK, &prev, NULL);
+ }
return;
}
@@ -620,3 +642,16 @@ void builtin_command_quit()
{
exit(0);
}
+
+// return true if suspended, otherwise false
+bool job_suspend(struct job_t *jobs, pid_t pid) {
+ int i;
+
+ for (i = 0; i < MAXJOBS; i++)
+ if (jobs[i].pid == pid)
+ {
+ jobs[i].state = ST;
+ return true;
+ }
+ return false;
+}