My Project
omFindExec.c
Go to the documentation of this file.
1 /*******************************************************************
2  * File: omFindExec.c
3  * Purpose: routine which determines absolute pathname of executable
4  * Author: obachman (Olaf Bachmann)
5  * Created: 11/99
6  *******************************************************************/
7 
8 
9 #include "singular_resourcesconfig.h"
10 
11 
12 #if defined(HAVE_UNISTD_H) && defined(STDC_HEADERS)
13 
14 #ifdef HAVE_UNISTD_H
15 #include <unistd.h> /* always defiend */
16 #endif
17 
18 #include <stdlib.h>
19 #include <string.h>
20 
21 #include "omFindExec.h"
22 
23 #ifndef MAXPATHLEN
24 #define MAXPATHLEN 1024
25 #endif
26 
27 /* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
28 #define ABSOLUTE_FILENAME_P(fname) (fname[0] == '/')
29 
30 /* Return the absolute name of the program named NAME. This function
31  searches the directories in the PATH environment variable if PROG
32  has no directory components. */
33 #ifndef HAVE_READLINK
34 char * omFindExec (const char *name, char* executable)
35 #else
36 static char * omFindExec_link (const char *name, char* executable)
37 #endif
38 {
39  char *search;
40  char *p;
41  char tbuf[MAXPATHLEN];
42 
43  if (ABSOLUTE_FILENAME_P(name))
44  {
45  /* If the named file exists then return it. */
46  if (! access (name, F_OK)) //think of libSingular.so as main binary
47  // r or x is required
48  {
49  strcpy(executable, name);
50  return executable;
51  }
52  }
53  else
54  {
55  if (((name[0] == '.') && (name[1] == '/')) ||
56  ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
57  strchr(name, '/') != NULL)
58  {
59  short ok=1;
60 
61 #ifdef HAVE_GETCWD
62  if (getcwd (tbuf, MAXPATHLEN)==NULL) ok=0;
63 #else
64 # ifdef HAVE_GETWD
65  if (getwd (tbuf)==NULL) ok=0;
66 # endif
67 #endif
68  strcat (tbuf, "/");
69  strcat (tbuf, name);
70  if (ok && ! access(tbuf, F_OK))
71  {
72  strcpy(executable, tbuf);
73  return executable;
74  }
75  }
76 
77 
78  search = getenv("PATH");
79 /* for winnt under msdos, cwd is implictly in the path */
80  p = search;
81 
82  if (p != NULL)
83  {
84  while (1)
85  {
86  char *next;
87  next = tbuf;
88 
89  /* Copy directory name into [tbuf]. */
90  /* This is somewhat tricky: empty names mean cwd, w.r.t. some
91  shell spec */
92  while (*p && *p != ':')
93  *next ++ = *p ++;
94  *next = '\0';
95 
96  if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
97 #ifdef HAVE_GETCWD
98  getcwd (tbuf, MAXPATHLEN);
99 #else
100 # ifdef HAVE_GETWD
101  getwd (tbuf);
102 # endif
103 #endif
104  }
105 
106  if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
107  strcat (tbuf, name);
108 
109  /* If the named file exists, then return it. */
110  if (! access (tbuf, F_OK))
111  {
112  strcpy(executable, tbuf);
113  return executable;
114  }
115 
116  if (*p != '\0')
117  {
118  p ++;
119  }
120  else
121  {
122  break;
123  }
124  }
125  }
126  /* try again with LD_LIBRARY_PATH */
127  search = getenv("LD_LIBRARY_PATH");
128  p = search;
129 
130  if ((p != NULL)&&(strlen(p)>1))
131  {
132  while (1)
133  {
134  char *next;
135  next = tbuf;
136 
137  /* Copy directory name into [tbuf]. */
138  /* This is somewhat tricky: empty names mean cwd, w.r.t. some
139  shell spec */
140  while (*p && *p != ':')
141  *next ++ = *p ++;
142  *next = '\0';
143 
144  if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
145  strcat (tbuf, name);
146 
147  /* If the named file exists, then return it. */
148  if (! access (tbuf, F_OK))
149  {
150  strcpy(executable, tbuf);
151  return executable;
152  }
153 
154  if (*p != '\0')
155  {
156  p ++;
157  }
158  else
159  {
160  break;
161  }
162  }
163  }
164  }
165  /* everything failed, so try the compiled path: */
166  strcpy(tbuf,BIN_DIR);
167  strcat(tbuf,"/");
168  strcat(tbuf,name);
169  /* If the named file exists, then return it. */
170  if (! access (tbuf, F_OK))
171  {
172  strcpy(executable, tbuf);
173  return executable;
174  }
175  strcpy(tbuf,LIB_DIR);
176  strcat(tbuf,"/");
177  strcat(tbuf,name);
178  /* If the named file exists, then return it. */
179  if (! access (tbuf, F_OK))
180  {
181  strcpy(executable, tbuf);
182  /* LIB_DIR is not reliable (may be set out of the Singular tree),
183  * so check also path for standard.lib*/
184  strcpy(tbuf,LIB_DIR);
185  strcat(tbuf,"/../share/singular/LIB/standard.lib");
186  if (! access (tbuf, R_OK))
187  return executable;
188  }
189  return NULL;
190 }
191 
192 #ifdef HAVE_READLINK
193 /* similar to readlink, but dont' mess up absolute pathnames */
194 static int my_readlink(const char* name, char* buf, size_t bufsize)
195 {
196  char buf2[MAXPATHLEN];
197  int ret;
198 
199  if ((ret = readlink(name, buf2, bufsize)) > 0)
200  {
201  buf2[ret] = 0;
202  if (*name == '/' && *buf2 != '/')
203  {
204  char* last = strrchr(name, '/');
205  int i = 0;
206  while (&(name[i]) != last)
207  {
208  buf[i] = name[i];
209  i++;
210  }
211  buf[i] = '/';
212  i++;
213  strcpy(&(buf[i]), buf2);
214  return i + ret;
215  }
216  else
217  {
218  strcpy(buf, buf2);
219  }
220  }
221  return ret;
222 }
223 
224 #define MAX_LINK_LEVEL 10
225 /* similar to readlink (cf. man readlink), except that symbolic links are
226  followed up to MAX_LINK_LEVEL
227 */
228 static int full_readlink(const char* name, char* buf, size_t bufsize)
229 {
230  int ret;
231 
232  if ((ret=my_readlink(name, buf, bufsize)) > 0)
233  {
234  char buf2[MAXPATHLEN];
235  int ret2, i = 0;
236 
237  do
238  {
239  buf[ret] = '\0';
240  if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
241  {
242  i++;
243  buf2[ret2] = '\0';
244  strcpy(buf, buf2);
245  ret = ret2;
246  }
247  else
248  {
249  return ret;
250  }
251  }
252  while (i<MAX_LINK_LEVEL);
253  }
254  return -1;
255 }
256 
257 #ifdef __CYGWIN__
258 /* for windows, serch first for .exe */
259 char * _omFindExec (const char *name, char* exec);
260 char* omFindExec(const char *name, char* exec)
261 {
262 
263  if (strstr(name, ".exe") == NULL)
264  {
265  char buf[MAXPATHLEN];
266  char* ret;
267  strcpy(buf, name);
268  strcat(buf, ".exe");
269  ret = _omFindExec(buf, exec);
270  if (ret != NULL) return ret;
271  }
272  return _omFindExec(name, exec);
273 }
274 #else
275 #define _omFindExec omFindExec
276 #endif
277 
278 char * _omFindExec (const char *name, char* exec)
279 {
280  char * link = omFindExec_link(name, exec);
281  char buf[MAXPATHLEN];
282  int ret;
283 
284  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
285  {
286  buf[ret] ='\0';
287  link = omFindExec_link(buf, exec);
288  }
289  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
290  {
291  char *p = strrchr(link, '/');
292 
293 
294  if(p!=NULL) *(p+1)='\0';
295  buf[ret]='\0';
296 
297  if (buf[0] != '/')
298  {
299  strcpy(exec, link);
300  strcat(exec, buf);
301  }
302  else
303  {
304  strcpy(exec, buf);
305  }
306 
307  return exec;
308  }
309  return link;
310 }
311 #endif /* HAVE_READLINK */
312 
313 #else
314 
315 char* omFindExec (const char *name, char* exec)
316 {
317  return name;
318 }
319 
320 #endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
int i
Definition: cfEzgcd.cc:132
int p
Definition: cfModGcd.cc:4078
CanonicalForm buf2
Definition: facFqBivar.cc:73
int search(const CFArray &A, const CanonicalForm &F, int i, int j)
search for F in A between index i and j
char name(const Variable &v)
Definition: factory.h:189
char * getenv()
STATIC_VAR poly last
Definition: hdegree.cc:1173
ListNode * next
Definition: janet.h:31
char * omFindExec(const char *name, char *exec)
Definition: omFindExec.c:315
#define NULL
Definition: omList.c:12
#define MAXPATHLEN
Definition: omRet2Info.c:22
int status int void * buf
Definition: si_signals.h:59