986ec39affa94f3e8b8fd0a75a27cf16f1fad26d — Simon Ser 15 days ago a6311b0
Send SIGHUP on exit only if job control is enabled
5 files changed, 28 insertions(+), 20 deletions(-)

M include/shell/job.h
M include/shell/process.h
M shell/job.c
M shell/process.c
M shell/shell.c
M include/shell/job.h => include/shell/job.h +4 -0
@@ 95,5 95,9 @@ struct mrsh_job *job_by_id(struct mrsh_state *state,
  * Return a string describing the process' state. `r` is a random boolean.
  */
 const char *job_state_str(struct mrsh_job *job, bool r);
+/**
+ * Send SIGHUP to all running jobs.
+ */
+void broadcast_sighup_to_jobs(struct mrsh_state *state);
 
 #endif

M include/shell/process.h => include/shell/process.h +0 -4
@@ 38,9 38,5 @@ int process_poll(struct mrsh_process *process);
  * Update the shell's state with a child process status.
  */
 void update_process(struct mrsh_state *state, pid_t pid, int stat);
-/**
- * Send SIGHUP to all child processes.
- */
-void broadcast_sighup(struct mrsh_state *state);
 
 #endif

M shell/job.c => shell/job.c +21 -1
@@ 182,6 182,11 @@ bool job_set_foreground(struct mrsh_job *job, bool foreground, bool cont) {
 
 	assert(job->pgid > 0);
 
+	if (!priv->job_control) {
+		fprintf(stderr, "job_set_foreground called with job control disabled\n");
+		return false;
+	}
+
 	// Don't try to continue the job if it's not stopped
 	if (job_poll(job) != TASK_STATUS_STOPPED) {
 		cont = false;


@@ 273,7 278,7 @@ static bool _job_wait(struct mrsh_state *state, pid_t pid, int options) {
 			if (errno == EINTR) {
 				continue;
 			}
-			perror("waitpid");
+			fprintf(stderr, "waitpid(%d): %s\n", pid, strerror(errno));
 			return false;
 		}
 		assert(ret == pid);


@@ 506,3 511,18 @@ const char *job_state_str(struct mrsh_job *job, bool r) {
 		return "Done";
 	}
 }
+
+void broadcast_sighup_to_jobs(struct mrsh_state *state) {
+	struct mrsh_state_priv *priv = state_get_priv(state);
+	assert(priv->job_control);
+
+	for (size_t i = 0; i < priv->jobs.len; ++i) {
+		struct mrsh_job *job = priv->jobs.data[i];
+		if (job_poll(job) >= 0) {
+			continue;
+		}
+		if (kill(-job->pgid, SIGHUP) != 0) {
+			perror("kill");
+		}
+	}
+}

M shell/process.c => shell/process.c +0 -14
@@ 80,17 80,3 @@ void update_process(struct mrsh_state *state, pid_t pid, int stat) {
 		assert(false);
 	}
 }
-
-void broadcast_sighup(struct mrsh_state *state) {
-	struct mrsh_state_priv *priv = state_get_priv(state);
-
-	for (size_t i = 0; i < priv->processes.len; ++i) {
-		struct mrsh_process *proc = priv->processes.data[i];
-		if (process_poll(proc) >= 0) {
-			continue;
-		}
-		if (kill(proc->pid, SIGHUP) != 0) {
-			perror("kill");
-		}
-	}
-}

M shell/shell.c => shell/shell.c +3 -1
@@ 85,7 85,9 @@ static void call_frame_destroy(struct mrsh_call_frame *frame) {
 
 void mrsh_state_destroy(struct mrsh_state *state) {
 	struct mrsh_state_priv *priv = state_get_priv(state);
-	broadcast_sighup(state);
+	if (priv->job_control) {
+		broadcast_sighup_to_jobs(state);
+	}
 	mrsh_hashtable_for_each(&priv->variables, state_var_finish_iterator, NULL);
 	mrsh_hashtable_finish(&priv->variables);
 	mrsh_hashtable_for_each(&priv->functions, state_fn_finish_iterator, NULL);