source: git/resources/omFindExec.c @ 5a0dde7

fieker-DuValspielwiese
Last change on this file since 5a0dde7 was 067348, checked in by Hans Schoenemann <hannes@…>, 19 months ago
fix: compiler warning
  • Property mode set to 100644
File size: 6.7 KB
Line 
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
34char * omFindExec (const char *name, char* executable)
35#else
36static 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 */
194static 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*/
228static 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 */
259char * _omFindExec (const char *name, char* exec);
260char* 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
278char * _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
315char* omFindExec (const char *name, char* exec)
316{
317  return name;
318}
319
320#endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Note: See TracBrowser for help on using the repository browser.