~emersion/mrsh

ref: ld-export mrsh/shell/path.c -rw-r--r-- 967 bytes
c5862d1bemersion meson: fix FreeBSD -Wl,--version-script detection 1 year, 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#define _POSIX_C_SOURCE 200809L
#include <limits.h>
#include <mrsh/shell.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "shell/path.h"

const char *expand_path(struct mrsh_state *state, const char *file, bool exec) {
	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 *basedir = strtok(pathe, ":");
	while (basedir) {
		int blen = strlen(basedir);
		if (blen == 0) {
			goto next;
		}
		bool slash = basedir[blen - 1] == '/';
		size_t n = snprintf(path, sizeof(path), "%s%s%s",
				basedir, slash ? "" : "/", file);
		if (n >= sizeof(path)) {
			goto next;
		}
		if (access(path, exec ? X_OK : R_OK) != -1) {
			free(pathe);
			return path;
		}
next:
		basedir = strtok(NULL, ":");
	}
	free(pathe);
	return NULL;
}