c6fc68bd180cc9821699736a32ee9201661dad69 — Simon Ser 24 days ago ae41141
builtin/command: implement -p
M builtin/command.c => builtin/command.c +4 -7
@@ 11,7 11,8 @@ static const char command_usage[] = "usage: command [-v|-V|-p] "
  	"command_name [argument...]\n";
  
- static int verify_command(struct mrsh_state *state, const char *command_name) {
+ static int verify_command(struct mrsh_state *state, const char *command_name,
+ 		bool default_path) {
  	size_t len_command_name = strlen(command_name);
  
  	const char *look_alias =


@@ 41,7 42,7 @@ }
  	}
  
- 	const char *expanded = expand_path(state, command_name, 1);
+ 	const char *expanded = expand_path(state, command_name, true, default_path);
  	if (expanded != NULL) {
  		printf("%s\n", expanded);
  		return 0;


@@ 74,16 75,12 @@ }
  	}
  
- 	if (default_path) {
- 		fprintf(stderr, "command: `-p` not yet implemented\n");
- 		return 1;
- 	}
  	if (verify) {
  		if (mrsh_optind != argc - 1) {
  			fprintf(stderr, command_usage);
  			return 1;
  		}
- 		return verify_command(state, argv[mrsh_optind]);
+ 		return verify_command(state, argv[mrsh_optind], default_path);
  	}
  
  	fprintf(stderr, "command: executing not yet implemented\n");

M builtin/dot.c => builtin/dot.c +1 -1
@@ 19,7 19,7 @@ return 1;
  	}
  
- 	const char *path = expand_path(state, argv[1], false);
+ 	const char *path = expand_path(state, argv[1], false, false);
  	if (!path) {
  		fprintf(stderr, "%s: not found\n", argv[1]);
  		if (!state->interactive) {

M builtin/hash.c => builtin/hash.c +1 -1
@@ 41,7 41,7 @@ continue;
  		}
  
- 		const char *path = expand_path(state, utility, true);
+ 		const char *path = expand_path(state, utility, true, false);
  		if (path == NULL) {
  			fprintf(stderr, "hash: command not found: %s\n", utility);
  			return 1;

M builtin/type.c => builtin/type.c +1 -1
@@ 35,7 35,7 @@ continue;
  		}
  
- 		const char *path = expand_path(state, name, true);
+ 		const char *path = expand_path(state, name, true, false);
  		if (path) {
  			fprintf(stdout, "%s is %s\n", name, path);
  			continue;

M include/shell/path.h => include/shell/path.h +7 -3
@@ 4,9 4,13 @@ #include <mrsh/shell.h>
  #include <stdbool.h>
  
- /** Searches $PATH for the requested file and returns it if found. If exec is
+ /* Searches $PATH for the requested file and returns it if found. If exec is
   * true, it will require the file to be executable in order to be considered a
-  * match. Fully qualified paths are returned as-is. */
- const char *expand_path(struct mrsh_state *state, const char *file, bool exec);
+  * match. If default_path is true, the system's default search path will be
+  * used instead of the $PATH variable. Fully qualified paths are returned
+  * as-is.
+  */
+ const char *expand_path(struct mrsh_state *state, const char *file, bool exec,
+ 	bool default_path);
  
  #endif

M shell/path.c => shell/path.c +28 -9
@@ 8,19 8,38 @@ #include <unistd.h>
  #include "shell/path.h"
  
- const char *expand_path(struct mrsh_state *state, const char *file, bool exec) {
+ const char *expand_path(struct mrsh_state *state, const char *file, bool exec,
+ 		bool default_path) {
  	if (strchr(file, '/')) {
  		return file;
  	}
- 	static char path[PATH_MAX + 1];
- 	const char *_pathe = mrsh_env_get(state, "PATH", NULL);
- 	if (!_pathe) {
- 		return NULL;
- 	}
- 	char *pathe = strdup(_pathe);
- 	if (!pathe) {
- 		return NULL;
+ 
+ 	char *pathe;
+ 	if (!default_path) {
+ 		const char *_pathe = mrsh_env_get(state, "PATH", NULL);
+ 		if (!_pathe) {
+ 			return NULL;
+ 		}
+ 		pathe = strdup(_pathe);
+ 		if (!pathe) {
+ 			return NULL;
+ 		}
+ 	} else {
+ 		size_t pathe_size = confstr(_CS_PATH, NULL, 0);
+ 		if (pathe_size == 0) {
+ 			return NULL;
+ 		}
+ 		pathe = malloc(pathe_size);
+ 		if (pathe == NULL) {
+ 			return NULL;
+ 		}
+ 		if (confstr(_CS_PATH, pathe, pathe_size) != pathe_size) {
+ 			free(pathe);
+ 			return NULL;
+ 		}
  	}
+ 
+ 	static char path[PATH_MAX + 1];
  	char *basedir = strtok(pathe, ":");
  	while (basedir) {
  		int blen = strlen(basedir);

M shell/task/simple_command.c => shell/task/simple_command.c +1 -1
@@ 43,7 43,7 @@ // The pipeline is responsible for creating the job
  	assert(ctx->job != NULL);
  
- 	const char *path = expand_path(ctx->state, argv[0], true);
+ 	const char *path = expand_path(ctx->state, argv[0], true, false);
  	if (!path) {
  		fprintf(stderr, "%s: not found\n", argv[0]);
  		return TASK_STATUS_ERROR;