Ce code n'est pas tout à fait ce que vous voulez, car il exécute simplement aveuglément la première chose à laquelle il arrive. Mais vous pouvez modifier le code de recherche afin qu'au lieu d'appeler execve
, vous appelez access
puis stat
pour savoir si ce n'est pas un répertoire. Je pense que seule la dernière fonction, , doit être remplacée.
Dans la meilleure tradition Unix, le code est "auto-documenté" (c'est-à-dire non documenté).
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include "shellpath.h"
static void *malloc_check(const char *what, size_t n) {
void *p = malloc(n);
if (p == NULL) {
fprintf(stderr, "Cannot allocate %zu bytes to %s\n", n, what);
exit(2);
}
return p;
}
static char *strsave(const char *s, const char *lim) {
if (lim == NULL)
lim = s + strlen(s);
char *p = malloc_check("save string", lim - s + 1);
strncpy(p, s, lim-s);
p[lim-s] = '\0';
return p;
}
char ** shellpath(void) {
const char *path = getenv("PATH");
if (!path)
path = "/bin:/usr/bin:/usr/local/bin";
char **vector = // size is overkill
malloc_check("hold path elements", strlen(path) * sizeof(*vector));
const char *p = path;
int next = 0;
while (p) {
char *q = strchr(p, ':');
vector[next++] = strsave(p, q);
p = q ? q + 1 : NULL;
}
vector[next] = NULL;
return vector;
}
void freeshellpath (char *shellpath[]) {
for (int i = 0; shellpath[i]; i++)
free(shellpath[i]);
free(shellpath);
}
unsigned maxpathlen(char *path[], const char *base) {
unsigned blen = strlen(base);
unsigned n = 0;
for (int i = 0; path[i]; i++) {
unsigned pn = strlen(path[i]);
if (pn > n) n = pn;
}
return blen+n+1;
}
void execvepath(char *path[], const char *base, char *const argv[],
char *const envp[])
{
if (strchr(base, '/'))
execve(base, argv, envp);
else {
size_t maxlen = maxpathlen(path, base)+1;
char *buf = malloc_check("hold path", maxlen);
for (int i = 0; path[i]; i++) {
snprintf(buf, maxlen, "%s/%s", path[i], base);
execve(buf, argv, envp);
}
}
}
@diciu je sais que. C'est pourquoi je cherche un moyen d'amener C à chercher le nom de fichier dans ces chemins de la même manière que bash fait – Gary