HPCToolkit
pathfind.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //************************** System Include Files ***************************
48 
49 #ifdef NO_STD_CHEADERS
50 # include <string.h>
51 #else
52 # include <cstring>
53 using namespace std; // For compatibility with non-std C headers
54 #endif
55 
56 #include <unistd.h>
57 
58 //*************************** User Include Files ****************************
59 
60 #include "pathfind.h"
61 #include "CStrUtil.h" // for 'ssave' and 'sfree'
62 
63 #include "PathFindMgr.hpp"
64 
65 //*************************** Forward Declarations ***************************
66 
67 //***************************************************************************
68 
69 
70 char*
71 pathfind(const char* pathList,
72  const char* name,
73  const char* mode)
74 {
75  static __thread char* result = NULL;
76  int accessFlags = 0;
77  const char* path;
78  const char* sep;
79 
80  if (result) { sfree(result); result = NULL; }
81 
82  /* Check that name is plausible. */
83  if (name == NULL || *name == '\0')
84  return NULL;
85 
86  /* Convert mode chars to accessFlags, for use by access function. */
87  if (mode) {
88  if (strchr( mode, 'r' )) accessFlags |= R_OK;
89  if (strchr( mode, 'w' )) accessFlags |= W_OK;
90  if (strchr( mode, 'x' )) accessFlags |= X_OK;
91  }
92  if (!accessFlags) { accessFlags = F_OK; }
93 
94  /* If pathList is empty or name is absolute, don't search path for it. */
95  if (pathList == NULL || *pathList == '\0' || *name == '/') {
96  if (access( name, accessFlags ) >= 0) {
97  result = ssave(name);
98  }
99  return result;
100  }
101 
102  path = pathList;
103  while (path) {
104 
105  int len, pathLen, retval;
106  char* tmp;
107 
108  sep = strchr (path, ':');
109  pathLen = sep ? sep - path : strlen (path);
110  len = strlen (name) + 1;
111  if (pathLen) len += pathLen + 1;
112  tmp = new char[len];
113  if (pathLen) {
114  strncpy(tmp, path, pathLen);
115  tmp[pathLen] = '/'; // Can't use strcat, since tmp may not
116  tmp[pathLen+1] = '\0'; // be NULL-terminated following strncpy.
117  strcat (tmp, name);
118  }
119  else {
120  strcpy (tmp, name);
121  }
122 
123  retval = access( tmp, accessFlags );
124 #ifdef SELFTEST
125  printf ("Access %s == %d\n", tmp, retval);
126 #endif
127  if (retval >= 0) {
128  result = tmp;
129  return (result);
130  }
131  else {
132  delete[] tmp;
133  }
134 
135  path = sep ? sep + 1 : NULL;
136  }
137 
138  return NULL;
139 }
140 
141 
142 #ifdef SELFTEST
143 int
144 main (int argc, const char *argv[])
145 {
146  int i;
147  char* res;
148 
149  for (i = 1; i < argc; i++) {
150  res = pathfind (getenv ("PATH"), argv[i], "r");
151  printf("findpath(%s) == %s\n", argv[i], res ? res : "<<NULL>>");
152  }
153 }
154 #endif
char * ssave(const char *const str)
Definition: CStrUtil.cpp:94
void sfree(char *str)
Definition: CStrUtil.cpp:103
static char * tmp
Definition: tokenize.c:63
int main(int argc, char *argv[])
Definition: main.cpp:125
char * pathfind(const char *pathList, const char *name, const char *mode)
Definition: pathfind.cpp:71
#define NULL
Definition: ElfHelper.cpp:85