18a516b153f72788ac73ad1e63c21c1fe8b9764f — Simon Ser a month ago b8aa6b8
Improve docs
3 files changed, 46 insertions(+), 3 deletions(-)

M include/shell/job.h
M include/shell/process.h
M shell/job.c
M include/shell/job.h => include/shell/job.h +28 -1
@@ 12,19 12,40 @@ /**
   * A job is a set of processes, comprising a shell pipeline, and any processes
   * descended from it, that are all in the same process group.
+  *
+  * In practice, a single job is also created when executing an asynchronous
+  * command list.
+  *
+  * This object is guaranteed to be valid until either:
+  * - The job terminates
+  * - The shell is destroyed
   */
  struct mrsh_job {
  	pid_t pgid;
- 	struct termios term_modes;
+ 	struct termios term_modes; // only valid if stopped
  	struct mrsh_state *state;
  	struct mrsh_array processes; // struct process *
  };
  
+ /**
+  * Create a new job with the provided process group ID.
+  */
  struct mrsh_job *job_create(struct mrsh_state *state, pid_t pgid);
  void job_destroy(struct mrsh_job *job);
  void job_add_process(struct mrsh_job *job, struct process *proc);
+ /**
+  * Check whether all child processes have terminated. If there are no child
+  * processes in this job, returns true.
+  */
  bool job_terminated(struct mrsh_job *job);
+ /**
+  * Check whether there is at least one stopped child process and all others
+  * have terminated.
+  */
  bool job_stopped(struct mrsh_job *job);
+ /**
+  * Wait for the completion of the job.
+  */
  int job_wait(struct mrsh_job *job);
  /**
   * Put the job in the foreground or in the background. If the job is stopped and


@@ 32,7 53,13 @@ */
  bool job_set_foreground(struct mrsh_job *job, bool foreground, bool cont);
  
+ /**
+  * Initialize a child process state.
+  */
  bool init_job_child_process(struct mrsh_state *state);
+ /**
+  * Update the shell's state with a child process status.
+  */
  void update_job(struct mrsh_state *state, pid_t pid, int stat);
  
  #endif

M include/shell/process.h => include/shell/process.h +13 -1
@@ 17,13 17,25 @@ struct mrsh_state *state;
  	bool stopped;
  	bool terminated;
- 	int stat;
+ 	int stat; // only valid if terminated
  };
  
+ /**
+  * Register a new process.
+  */
  struct process *process_create(struct mrsh_state *state, pid_t pid);
  void process_destroy(struct process *process);
+ /**
+  * Polls the process' current status without blocking. Returns:
+  * - An integer >= 0 if the process has terminated
+  * - TASK_STATUS_STOPPED if the process is stopped
+  * - TASK_STATUS_WAIT if the process is running
+  */
  int process_poll(struct process *process);
  
+ /**
+  * Update the shell's state with a child process status.
+  */
  void update_process(struct mrsh_state *state, pid_t pid, int stat);
  
  #endif

M shell/job.c => shell/job.c +5 -1
@@ 149,8 149,10 @@   	if (foreground && state->foreground_job != job) {
  		assert(state->foreground_job == NULL);
+ 		// Put the job in the foreground
  		tcsetpgrp(state->fd, job->pgid);
  		if (cont) {
+ 			// Restore the job's terminal modes
  			tcsetattr(state->fd, TCSADRAIN, &job->term_modes);
  		}
  		state->foreground_job = job;


@@ 159,8 161,10 @@ if (!foreground && state->foreground_job == job) {
  		// Put the shell back in the foreground
  		tcsetpgrp(state->fd, state->pgid);
- 		// Restore the shell’s terminal modes
+ 		// Save the job's terminal modes, to restore them if it's put in the
+ 		// foreground again
  		tcgetattr(state->fd, &job->term_modes);
+ 		// Restore the shell’s terminal modes
  		tcsetattr(state->fd, TCSADRAIN, &state->term_modes);
  		state->foreground_job = NULL;
  	}