1c3aa85e5c60218d36c6353ed5bf330de66578d6
[oota-llvm.git] / tools / llee / SysUtils.c
1 //===- SystemUtils.h - Utilities to do low-level system stuff --*- C++ -*--===//
2 //
3 // This file contains functions used to do a variety of low-level, often
4 // system-specific, tasks.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "SysUtils.h"
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"
15 #include <stdlib.h>
16 #include <string.h>
17
18 /// isExecutableFile - This function returns true if the filename specified
19 /// exists and is executable.
20 ///
21 bool isExecutableFile(const char *ExeFileName) {
22   struct stat Buf;
23   if (stat(ExeFileName, &Buf))
24     return false;  // Must not be executable!
25
26   if (!(Buf.st_mode & S_IFREG))
27     return false;                    // Not a regular file?
28
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;
35 }
36
37 /// FindExecutable - Find a named executable in the directories listed in $PATH.
38 /// If the executable cannot be found, returns NULL.
39 /// 
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 "";
44
45   // Now we have a colon separated list of directories to search... try them...
46   unsigned PathLen = strlen(PathStr);
47   while (PathLen) {
48     /* Find the next colon */
49     const char *Colon = strchr(PathStr, ':');
50     
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));
54     unsigned i, e;
55     for (i = 0; i != DirLen; ++i)
56       FilePath[i] = PathStr[i];
57     FilePath[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! */
63
64     /* If Colon is NULL, there are no more colon separators and no more dirs */
65     if (!Colon) break;
66
67     /* Nope, it wasn't in this directory, check the next range! */
68     PathLen -= DirLen;
69     PathStr = Colon;
70     while (*PathStr == ':') {   /* Advance past colons */
71       PathStr++;
72       PathLen--;
73     }
74
75     /* Advance past the colon */
76     ++Colon;
77   }
78
79   // If we fell out, we ran out of directories in PATH to search, return failure
80   return NULL;
81 }