which - once a match is found in $PATH, test that it is a regular file
and can be accessed as executable
This commit is contained in:
parent
32b827061c
commit
2dcdba7704
@ -1,5 +1,7 @@
|
|||||||
# Makefile - hhl - /src/world/bin/which
|
# Makefile - hhl - /src/world/usr.bin/which
|
||||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||||
#
|
#
|
||||||
progname = which
|
progname = which
|
||||||
include hhl.script.mk
|
hhl_source = 1
|
||||||
|
onestage = true
|
||||||
|
include hhl.cprog.mk
|
||||||
|
57
world/usr.bin/which/src/which.c
Normal file
57
world/usr.bin/which/src/which.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include <dirent.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
char *__progname;
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
printf("Usage: %s [COMMAND]\n", __progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
char *path, *seg, *__path;
|
||||||
|
const char sep[2] = ":";
|
||||||
|
|
||||||
|
__progname = basename(argv[0]);
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "%s: Error: missing argument\n", __progname);
|
||||||
|
usage();
|
||||||
|
} else if (argc > 2) {
|
||||||
|
fprintf(stderr, "%s: Error: missing argument\n", __progname);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
path = getenv("PATH");
|
||||||
|
if (path == NULL) {
|
||||||
|
path = "/usr/bin:/bin";
|
||||||
|
}
|
||||||
|
// Save a copy for later use, since strtok will modify the original
|
||||||
|
__path = strndup(path, strlen(path) + 1);
|
||||||
|
seg = strtok(path, sep);
|
||||||
|
while (seg != NULL) {
|
||||||
|
struct dirent *dp;
|
||||||
|
DIR *dir = opendir(seg);
|
||||||
|
if (dir) {
|
||||||
|
while ((dp = readdir(dir)) != NULL) {
|
||||||
|
if (strcmp(argv[1], dp->d_name) == 0) {
|
||||||
|
char *p = malloc(strlen(argv[1] + strlen(seg) + 2));
|
||||||
|
(void)strncpy(p, seg, strlen(seg) + 1);
|
||||||
|
(void)strncat(p, "/", 2);
|
||||||
|
(void)strncat(p, argv[1], strlen(argv[1]) + 1);
|
||||||
|
struct stat path_stat;
|
||||||
|
stat(p, &path_stat);
|
||||||
|
if (access(p, X_OK) == 0 && S_ISREG(path_stat.st_mode)) {
|
||||||
|
printf("%s\n", p);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seg = strtok(NULL, sep);
|
||||||
|
}
|
||||||
|
printf("%s: no %s in (%s)\n", __progname, argv[1], __path);
|
||||||
|
}
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/zsh
|
|
||||||
which $@
|
|
Loading…
Reference in New Issue
Block a user