b8aa6b828d7be0f0340e57926990f9d474a63ccb — Simon Ser 3 months ago 7723619
Only create jobs if job control is enabled
5 files changed, 39 insertions(+), 32 deletions(-)

M builtin/set.c
M include/mrsh/shell.h
M shell/task/async.c
M shell/task/command_process.c
M shell/task/pipeline.c
M builtin/set.c => builtin/set.c +1 -0
@@ 191,6 191,7 @@ }
  
  int builtin_set(struct mrsh_state *state, int argc, char *argv[]) {
+ 	// TODO: support enabling/disabling job control at runtime
  	return set(state, NULL, argc, argv);
  }
  

M include/mrsh/shell.h => include/mrsh/shell.h +6 -5
@@ 29,11 29,12 @@ // are defined (the utilities are normally located when the function is
  	// executed).
  	MRSH_OPT_PRELOOKUP = 1 << 5,
- 	// -m: Immediately before the shell issues a prompt after completion of the
- 	// background job, a message reporting the exit status of the background job
- 	// shall be written to standard error. If a foreground job stops, the shell
- 	// shall write a message to standard error to that effect, formatted as
- 	// described by the jobs utility.
+ 	// -m: All jobs shall be run in their own process groups. Immediately before
+ 	// the shell issues a prompt after completion of the background job, a
+ 	// message reporting the exit status of the background job shall be written
+ 	// to standard error. If a foreground job stops, the shell shall write a
+ 	// message to standard error to that effect, formatted as described by the
+ 	// jobs utility.
  	MRSH_OPT_MONITOR = 1 << 6,
  	// -n: The shell shall read commands but does not execute them; this can be
  	// used to check for shell script syntax errors. An interactive shell may

M shell/task/async.c => shell/task/async.c +17 -13
@@ 46,12 46,14 @@ fprintf(stderr, "fork failed: %s\n", strerror(errno));
  		return false;
  	} else if (pid == 0) {
- 		// Create a job for all children processes
- 		pid_t pgid = create_process_group(getpid());
- 		if (pgid < 0) {
- 			exit(1);
+ 		if (ctx->state->options & MRSH_OPT_MONITOR) {
+ 			// Create a job for all children processes
+ 			pid_t pgid = create_process_group(getpid());
+ 			if (pgid < 0) {
+ 				exit(1);
+ 			}
+ 			ctx->job = job_create(ctx->state, pgid);
  		}
- 		ctx->job = job_create(ctx->state, pgid);
  
  		if (!(ctx->state->options & MRSH_OPT_MONITOR)) {
  			// If job control is disabled, stdin is /dev/null


@@ 73,15 75,17 @@ exit(ret);
  	}
  
- 	pid_t pgid = create_process_group(pid);
- 	if (pgid < 0) {
- 		return false;
- 	}
+ 	if (ctx->state->options & MRSH_OPT_MONITOR) {
+ 		pid_t pgid = create_process_group(pid);
+ 		if (pgid < 0) {
+ 			return false;
+ 		}
  
- 	// Create a background job
- 	struct process *proc = process_create(ctx->state, pid);
- 	struct mrsh_job *job = job_create(ctx->state, pgid);
- 	job_add_process(job, proc);
+ 		// Create a background job
+ 		struct process *proc = process_create(ctx->state, pid);
+ 		struct mrsh_job *job = job_create(ctx->state, pgid);
+ 		job_add_process(job, proc);
+ 	}
  
  	return true;
  }

M shell/task/command_process.c => shell/task/command_process.c +15 -10
@@ 41,11 41,13 @@ fprintf(stderr, "failed to fork(): %s\n", strerror(errno));
  		return false;
  	} else if (pid == 0) {
- 		struct mrsh_job *job = put_into_process_group(ctx, getpid());
- 		if (ctx->state->interactive && !ctx->background) {
- 			job_set_foreground(job, true, false);
+ 		if (ctx->state->options & MRSH_OPT_MONITOR) {
+ 			struct mrsh_job *job = put_into_process_group(ctx, getpid());
+ 			if (ctx->state->interactive && !ctx->background) {
+ 				job_set_foreground(job, true, false);
+ 			}
+ 			init_job_child_process(ctx->state);
  		}
- 		init_job_child_process(ctx->state);
  
  		for (size_t i = 0; i < sc->assignments.len; ++i) {
  			struct mrsh_assignment *assign = sc->assignments.data[i];


@@ 93,13 95,16 @@ exit(127);
  	}
  
- 	struct mrsh_job *job = put_into_process_group(ctx, pid);
- 	if (ctx->state->interactive && !ctx->background) {
- 		job_set_foreground(job, true, false);
- 	}
- 
  	tc->process = process_create(ctx->state, pid);
- 	job_add_process(job, tc->process);
+ 
+ 	if (ctx->state->options & MRSH_OPT_MONITOR) {
+ 		struct mrsh_job *job = put_into_process_group(ctx, pid);
+ 		if (ctx->state->interactive && !ctx->background) {
+ 			job_set_foreground(job, true, false);
+ 		}
+ 
+ 		job_add_process(job, tc->process);
+ 	}
  
  	return true;
  }

M shell/task/pipeline.c => shell/task/pipeline.c +0 -4
@@ 124,10 124,6 @@ }
  	}
  
- 	if (ret != TASK_STATUS_WAIT) {
- 		job_destroy(tp->child_ctx.job);
- 	}
- 
  	return ret;
  }