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"
19 * isExecutableFile - This function returns true if the filename specified
20 * exists and is executable.
22 unsigned isExecutableFile(const char *ExeFileName) {
24 if (stat(ExeFileName, &Buf))
25 return 0; // Must not be executable!
27 if (!(Buf.st_mode & S_IFREG))
28 return 0; // Not a regular file?
30 if (Buf.st_uid == getuid()) // Owner of file?
31 return Buf.st_mode & S_IXUSR;
32 else if (Buf.st_gid == getgid()) // In group of file?
33 return Buf.st_mode & S_IXGRP;
34 else // Unrelated to file?
35 return Buf.st_mode & S_IXOTH;
39 * FindExecutable - Find a named executable in the directories listed in $PATH.
40 * If the executable cannot be found, returns NULL.
42 char *FindExecutable(const char *ExeName) {
43 /* Try to find the executable in the path */
44 const char *PathStr = getenv("PATH");
45 if (PathStr == 0) return 0;
47 /* Now we have a colon separated list of directories to search, try them. */
48 unsigned PathLen = strlen(PathStr);
50 /* Find the next colon */
51 const char *Colon = strchr(PathStr, ':');
53 /* Check to see if this first directory contains the executable... */
54 unsigned DirLen = Colon ? (unsigned)(Colon-PathStr) : strlen(PathStr);
55 char *FilePath = alloca(sizeof(char) * (DirLen+1+strlen(ExeName)+1));
57 for (i = 0; i != DirLen; ++i)
58 FilePath[i] = PathStr[i];
60 for (i = 0, e = strlen(ExeName); i != e; ++i)
61 FilePath[DirLen + 1 + i] = ExeName[i];
62 FilePath[DirLen + 1 + i] = '\0';
63 if (isExecutableFile(FilePath))
64 return strdup(FilePath); /* Found the executable! */
66 /* If Colon is NULL, there are no more colon separators and no more dirs */
69 /* Nope, it wasn't in this directory, check the next range! */
72 while (*PathStr == ':') { /* Advance past colons */
77 /* Advance past the colon */
81 /* If we fell out, we ran out of directories to search, return failure. */