1 //===- SystemUtils.h - Utilities to do low-level system stuff --*- C++ -*--===//
3 // This file contains functions used to do a variety of low-level, often
4 // system-specific, tasks.
6 //===----------------------------------------------------------------------===//
9 #include "Config/sys/types.h"
10 #include "Config/sys/stat.h"
11 #include "Config/fcntl.h"
12 #include "Config/sys/wait.h"
13 #include "Config/unistd.h"
14 #include "Config/errno.h"
18 /// isExecutableFile - This function returns true if the filename specified
19 /// exists and is executable.
21 bool isExecutableFile(const char *ExeFileName) {
23 if (stat(ExeFileName, &Buf))
24 return false; // Must not be executable!
26 if (!(Buf.st_mode & S_IFREG))
27 return false; // Not a regular file?
29 if (Buf.st_uid == getuid()) // Owner of file?
30 return Buf.st_mode & S_IXUSR;
31 else if (Buf.st_gid == getgid()) // In group of file?
32 return Buf.st_mode & S_IXGRP;
33 else // Unrelated to file?
34 return Buf.st_mode & S_IXOTH;
37 /// FindExecutable - Find a named executable in the directories listed in $PATH.
38 /// If the executable cannot be found, returns NULL.
40 char *FindExecutable(const char *ExeName) {
41 /* Try to find the executable in the path */
42 const char *PathStr = getenv("PATH");
43 if (PathStr == 0) return "";
45 // Now we have a colon separated list of directories to search... try them...
46 unsigned PathLen = strlen(PathStr);
48 /* Find the next colon */
49 const char *Colon = strchr(PathStr, ':');
51 /* Check to see if this first directory contains the executable... */
52 unsigned DirLen = Colon ? (Colon-PathStr) : strlen(PathStr);
53 char *FilePath = alloca(sizeof(char) * (DirLen+1+strlen(ExeName)+1));
55 for (i = 0; i != DirLen; ++i)
56 FilePath[i] = PathStr[i];
58 for (i = 0, e = strlen(ExeName); i != e; ++i)
59 FilePath[DirLen + 1 + i] = ExeName[i];
60 FilePath[DirLen + 1 + i] = '\0';
61 if (isExecutableFile(FilePath))
62 return strdup(FilePath); /* Found the executable! */
64 /* If Colon is NULL, there are no more colon separators and no more dirs */
67 /* Nope, it wasn't in this directory, check the next range! */
70 while (*PathStr == ':') { /* Advance past colons */
75 /* Advance past the colon */
79 // If we fell out, we ran out of directories in PATH to search, return failure