blob: 1c3aa85e5c60218d36c6353ed5bf330de66578d6 (
plain)
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
//===- SystemUtils.h - Utilities to do low-level system stuff --*- C++ -*--===//
//
// This file contains functions used to do a variety of low-level, often
// system-specific, tasks.
//
//===----------------------------------------------------------------------===//
#include "SysUtils.h"
#include "Config/sys/types.h"
#include "Config/sys/stat.h"
#include "Config/fcntl.h"
#include "Config/sys/wait.h"
#include "Config/unistd.h"
#include "Config/errno.h"
#include <stdlib.h>
#include <string.h>
/// isExecutableFile - This function returns true if the filename specified
/// exists and is executable.
///
bool isExecutableFile(const char *ExeFileName) {
struct stat Buf;
if (stat(ExeFileName, &Buf))
return false; // Must not be executable!
if (!(Buf.st_mode & S_IFREG))
return false; // Not a regular file?
if (Buf.st_uid == getuid()) // Owner of file?
return Buf.st_mode & S_IXUSR;
else if (Buf.st_gid == getgid()) // In group of file?
return Buf.st_mode & S_IXGRP;
else // Unrelated to file?
return Buf.st_mode & S_IXOTH;
}
/// FindExecutable - Find a named executable in the directories listed in $PATH.
/// If the executable cannot be found, returns NULL.
///
char *FindExecutable(const char *ExeName) {
/* Try to find the executable in the path */
const char *PathStr = getenv("PATH");
if (PathStr == 0) return "";
// Now we have a colon separated list of directories to search... try them...
unsigned PathLen = strlen(PathStr);
while (PathLen) {
/* Find the next colon */
const char *Colon = strchr(PathStr, ':');
/* Check to see if this first directory contains the executable... */
unsigned DirLen = Colon ? (Colon-PathStr) : strlen(PathStr);
char *FilePath = alloca(sizeof(char) * (DirLen+1+strlen(ExeName)+1));
unsigned i, e;
for (i = 0; i != DirLen; ++i)
FilePath[i] = PathStr[i];
FilePath[i] = '/';
for (i = 0, e = strlen(ExeName); i != e; ++i)
FilePath[DirLen + 1 + i] = ExeName[i];
FilePath[DirLen + 1 + i] = '\0';
if (isExecutableFile(FilePath))
return strdup(FilePath); /* Found the executable! */
/* If Colon is NULL, there are no more colon separators and no more dirs */
if (!Colon) break;
/* Nope, it wasn't in this directory, check the next range! */
PathLen -= DirLen;
PathStr = Colon;
while (*PathStr == ':') { /* Advance past colons */
PathStr++;
PathLen--;
}
/* Advance past the colon */
++Colon;
}
// If we fell out, we ran out of directories in PATH to search, return failure
return NULL;
}
|