~emersion/mrsh-dev

Store command string for job in command_process v1 PROPOSED

Drew DeVault: 1
 Store command string for job in command_process

 4 files changed, 34 insertions(+), 9 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~emersion/mrsh-dev/patches/6053/mbox | git am -3
Learn more about email & git

[PATCH] Store command string for job in command_process Export this patch

---
This is necessary for certain kinds of job IDs, and for the jobs
builtin. I also left TODOs in two more places where we have to fish in
the command string - but these are going to be a lot more difficult.
We'll have to attach the original AST to the tasks, then rebuild the
command string from the AST.

 include/shell/job.h          |  4 +++-
 shell/job.c                  |  7 +++++--
 shell/shell.c                |  6 ++++--
 shell/task/command_process.c | 26 ++++++++++++++++++++++----
 4 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/include/shell/job.h b/include/shell/job.h
index f7e8a37..c16e6ce 100644
--- a/include/shell/job.h
+++ b/include/shell/job.h
@@ -23,6 +23,7 @@ struct process;
 struct mrsh_job {
 	pid_t pgid;
 	int job_id;
+	char *command;
 	struct termios term_modes; // only valid if stopped
 	struct mrsh_state *state;
 	struct mrsh_array processes; // struct process *
@@ -31,7 +32,8 @@ struct mrsh_job {
 /**
  * Create a new job with the provided process group ID.
  */
-struct mrsh_job *job_create(struct mrsh_state *state, pid_t pgid);
+struct mrsh_job *job_create(struct mrsh_state *state,
+		pid_t pgid, const char *command);
 void job_destroy(struct mrsh_job *job);
 void job_add_process(struct mrsh_job *job, struct process *proc);
 /**
diff --git a/shell/job.c b/shell/job.c
index b3dc2f1..42d5a31 100644
--- a/shell/job.c
+++ b/shell/job.c
@@ -1,4 +1,4 @@
-#define _POSIX_C_SOURCE 1
+#define _POSIX_C_SOURCE 200809L
 #include <assert.h>
 #include <errno.h>
 #include <mrsh/array.h>
@@ -83,7 +83,8 @@ static void array_remove(struct mrsh_array *array, size_t i) {
 	--array->len;
 }
 
-struct mrsh_job *job_create(struct mrsh_state *state, pid_t pgid) {
+struct mrsh_job *job_create(
+		struct mrsh_state *state, pid_t pgid, const char *command) {
 	int id = 1;
 	for (size_t i = 0; i < state->jobs.len; ++i) {
 		struct mrsh_job *job = state->jobs.data[i];
@@ -101,6 +102,7 @@ struct mrsh_job *job_create(struct mrsh_state *state, pid_t pgid) {
 	job->state = state;
 	job->pgid = pgid;
 	job->job_id = id;
+	job->command = strdup(command);
 	mrsh_array_add(&state->jobs, job);
 	return job;
 }
@@ -126,6 +128,7 @@ void job_destroy(struct mrsh_job *job) {
 		process_destroy(job->processes.data[j]);
 	}
 	mrsh_array_finish(&job->processes);
+	free(job->command);
 	free(job);
 }
 
diff --git a/shell/shell.c b/shell/shell.c
index 627e8c7..ec855b3 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -188,7 +188,8 @@ pid_t subshell_fork(struct context *ctx, struct process **process_ptr) {
 			if (pgid < 0) {
 				exit(1);
 			}
-			ctx->job = job_create(ctx->state, pgid);
+			/* TODO: Fill in the command string */
+			ctx->job = job_create(ctx->state, pgid, "TODO");
 
 			if (ctx->state->interactive && !ctx->background) {
 				job_set_foreground(ctx->job, true, false);
@@ -211,7 +212,8 @@ pid_t subshell_fork(struct context *ctx, struct process **process_ptr) {
 			return false;
 		}
 
-		struct mrsh_job *job = job_create(ctx->state, pgid);
+		/* TODO: Fill in the command string */
+		struct mrsh_job *job = job_create(ctx->state, pgid, "TODO");
 		job_add_process(job, proc);
 
 		if (ctx->state->interactive && !ctx->background) {
diff --git a/shell/task/command_process.c b/shell/task/command_process.c
index dd21e84..a6c1a08 100644
--- a/shell/task/command_process.c
+++ b/shell/task/command_process.c
@@ -19,9 +19,26 @@ static void populate_env_iterator(const char *key, void *_var, void *_) {
  * Put the process into its job's process group. This has to be done both in the
  * parent and the child because of potential race conditions.
  */
-static struct mrsh_job *put_into_process_group(struct context *ctx, pid_t pid) {
+static struct mrsh_job *put_into_process_group(
+		struct context *ctx, pid_t pid, char **argv) {
+	size_t cmdlen = 0;
+	for (int i = 0; argv[i]; ++i) {
+		cmdlen += strlen(argv[i]);
+		if (argv[i + 1]) {
+			cmdlen += 1;
+		}
+	}
+	char *cmd = malloc(cmdlen + 1);
+	cmd[0] = '\0';
+	for (int i = 0; argv[i]; ++i) {
+		strcat(cmd, argv[i]);
+		if (argv[i + 1]) {
+			strcat(cmd, " ");
+		}
+	}
+
 	if (ctx->job == NULL) {
-		ctx->job = job_create(ctx->state, pid);
+		ctx->job = job_create(ctx->state, pid, cmd);
 	}
 	setpgid(pid, ctx->job->pgid);
 	return ctx->job;
@@ -42,7 +59,8 @@ static bool task_process_start(struct task_command *tc, struct context *ctx) {
 		return false;
 	} else if (pid == 0) {
 		if (ctx->state->options & MRSH_OPT_MONITOR) {
-			struct mrsh_job *job = put_into_process_group(ctx, getpid());
+			struct mrsh_job *job =
+				put_into_process_group(ctx, getpid(), argv);
 			if (ctx->state->interactive && !ctx->background) {
 				job_set_foreground(job, true, false);
 			}
@@ -98,7 +116,7 @@ static bool task_process_start(struct task_command *tc, struct context *ctx) {
 	tc->process = process_create(ctx->state, pid);
 
 	if (ctx->state->options & MRSH_OPT_MONITOR) {
-		struct mrsh_job *job = put_into_process_group(ctx, pid);
+		struct mrsh_job *job = put_into_process_group(ctx, pid, argv);
 		if (ctx->state->interactive && !ctx->background) {
 			job_set_foreground(job, true, false);
 		}
-- 
2.21.0
View this thread in the archives