M builtin/builtin.c => builtin/builtin.c +2 -1
@@ 28,6 28,7 @@ static const struct builtin builtins[] = {
{ "false", builtin_false, false },
{ "fg", builtin_fg, false },
{ "getopts", builtin_getopts, false },
+ { "hash", builtin_hash, false },
{ "jobs", builtin_jobs, false },
{ "pwd", builtin_pwd, false },
{ "read", builtin_read, false },
@@ 69,7 70,7 @@ static int builtin_compare(const void *_a, const void *_b) {
static int unspecified_compare(const void *_a, const void *_b) {
const char *a = _a;
- const char * const *b = _b;
+ const char *const *b = _b;
return strcmp(a, *b);
}
A builtin/hash.c => builtin/hash.c +52 -0
@@ 0,0 1,52 @@
+#include <mrsh/getopt.h>
+#include <mrsh/builtin.h>
+#include <shell/path.h>
+#include <stdio.h>
+#include <string.h>
+#include "builtin.h"
+
+static const char hash_usage[] = "usage: hash -r|utility...\n";
+
+int builtin_hash(struct mrsh_state *state, int argc, char *argv[]) {
+ /* Hashing and remembering executable location isn't implemented. Thus most
+ * of this builtin just does nothing. */
+ mrsh_optind = 0;
+ int opt;
+ while ((opt = mrsh_getopt(argc, argv, ":r")) != -1) {
+ switch (opt) {
+ case 'r':
+ /* no-op: reset list of cached utilities */
+ return 0;
+ default:
+ fprintf(stderr, "hash: unknown option -- %c\n", mrsh_optopt);
+ fprintf(stderr, hash_usage);
+ return 1;
+ }
+ }
+
+ if (argc == 1) {
+ /* no-op: print list of cached utilities */
+ return 0;
+ }
+
+ for (int i = 1; i < argc; i++) {
+ const char *utility = argv[i];
+ if (strchr(utility, '/') != NULL) {
+ fprintf(stderr,
+ "hash: undefined behaviour: utility contains a slash\n");
+ return 1;
+ }
+
+ if (mrsh_has_builtin(utility)) {
+ continue;
+ }
+
+ const char *path = expand_path(state, utility, true);
+ if (path == NULL) {
+ fprintf(stderr, "hash: command not found: %s\n", utility);
+ return 1;
+ }
+ }
+
+ return 0;
+}
M configure => configure +1 -0
@@ 47,6 47,7 @@ libmrsh() {
'builtin/false.c' \
'builtin/fg.c' \
'builtin/getopts.c' \
+ 'builtin/hash.c' \
'builtin/jobs.c' \
'builtin/pwd.c' \
'builtin/read.c' \
M include/builtin.h => include/builtin.h +1 -0
@@ 21,6 21,7 @@ int builtin_export(struct mrsh_state *state, int argc, char *argv[]);
int builtin_false(struct mrsh_state *state, int argc, char *argv[]);
int builtin_fg(struct mrsh_state *state, int argc, char *argv[]);
int builtin_getopts(struct mrsh_state *state, int argc, char *argv[]);
+int builtin_hash(struct mrsh_state *state, int argc, char *argv[]);
int builtin_jobs(struct mrsh_state *state, int argc, char *argv[]);
int builtin_pwd(struct mrsh_state *state, int argc, char *argv[]);
int builtin_read(struct mrsh_state *state, int argc, char *argv[]);
M meson.build => meson.build +1 -0
@@ 86,6 86,7 @@ lib_mrsh = library(
'builtin/false.c',
'builtin/fg.c',
'builtin/getopts.c',
+ 'builtin/hash.c',
'builtin/jobs.c',
'builtin/pwd.c',
'builtin/read.c',