source: git/resources/omFindExec.c @ 3824816

spielwiese
Last change on this file since 3824816 was f95481, checked in by Hans Schoenemann <hannes@…>, 7 years ago
omFindExec: test F_OK, not X_OK
  • Property mode set to 100644
File size: 5.2 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
60#ifdef HAVE_GETCWD
61      getcwd (tbuf, MAXPATHLEN);
62#else
63# ifdef HAVE_GETWD
64      getwd (tbuf);
65# endif
66#endif
67      strcat (tbuf, "/");
68      strcat (tbuf, name);
69      if (! access(tbuf, F_OK))
70      {
71        strcpy(executable, tbuf);
72        return executable;
73      }
74    }
75
76
77    search = getenv("PATH");
78/* for winnt under msdos, cwd is implictly in the path */
79    p = search;
80
81    if (p != NULL)
82    {
83      while (1)
84      {
85        char *next;
86        next = tbuf;
87
88        /* Copy directory name into [tbuf]. */
89        /* This is somewhat tricky: empty names mean cwd, w.r.t. some
90           shell spec */
91        while (*p && *p != ':')
92          *next ++ = *p ++;
93        *next = '\0';
94
95        if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
96#ifdef HAVE_GETCWD
97          getcwd (tbuf, MAXPATHLEN);
98#else
99# ifdef HAVE_GETWD
100          getwd (tbuf);
101# endif
102#endif
103        }
104
105        if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
106        strcat (tbuf, name);
107
108        /* If the named file exists, then return it. */
109        if (! access (tbuf, F_OK))
110        {
111          strcpy(executable, tbuf);
112          return executable;
113        }
114
115        if (*p != '\0')
116        {
117          p ++;
118        }
119        else
120        {
121          break;
122        }
123      }
124    }
125  }
126  return NULL;
127}
128
129#ifdef HAVE_READLINK
130/* similar to readlink, but dont' mess up absolute pathnames */
131static int my_readlink(const char* name, char* buf, size_t bufsize)
132{
133  char buf2[MAXPATHLEN];
134  int ret;
135
136  if ((ret = readlink(name, buf2, bufsize)) > 0)
137  {
138    buf2[ret] = 0;
139    if (*name == '/' && *buf2 != '/')
140    {
141      char* last = strrchr(name, '/');
142      int i = 0;
143      while (&(name[i]) != last)
144      {
145        buf[i] = name[i];
146        i++;
147      }
148      buf[i] = '/';
149      i++;
150      strcpy(&(buf[i]), buf2);
151      return i + ret;
152    }
153    else
154    {
155      strcpy(buf, buf2);
156    }
157  }
158  return ret;
159}
160
161#define MAX_LINK_LEVEL 10
162/* similar to readlink (cf. man readlink), except that symbolic links are
163   followed up to MAX_LINK_LEVEL
164*/
165static int full_readlink(const char* name, char* buf, size_t bufsize)
166{
167  int ret;
168
169  if ((ret=my_readlink(name, buf, bufsize)) > 0)
170  {
171    char buf2[MAXPATHLEN];
172    int ret2, i = 0;
173
174    do
175    {
176      buf[ret] = '\0';
177      if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
178      {
179        i++;
180        buf2[ret2] = '\0';
181        strcpy(buf, buf2);
182        ret = ret2;
183      }
184      else
185      {
186        return ret;
187      }
188    }
189    while (i<MAX_LINK_LEVEL);
190  }
191  return -1;
192}
193
194#ifdef __CYGWIN__
195/* for windows, serch first for .exe */
196char * _omFindExec (const char *name, char* exec);
197char* omFindExec(const char *name, char* exec)
198{
199
200  if (strstr(name, ".exe") == NULL)
201  {
202    char buf[MAXPATHLEN];
203    char* ret;
204    strcpy(buf, name);
205    strcat(buf, ".exe");
206    ret = _omFindExec(buf, exec);
207    if (ret != NULL) return ret;
208  }
209  return _omFindExec(name, exec);
210}
211#else
212#define _omFindExec omFindExec
213#endif
214
215char * _omFindExec (const char *name, char* exec)
216{
217  char * link = omFindExec_link(name, exec);
218  char buf[MAXPATHLEN];
219  int ret;
220
221  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
222  {
223    buf[ret] ='\0';
224    link = omFindExec_link(buf, exec);
225  }
226  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
227  {
228    char *p = strrchr(link, '/');
229
230
231    if(p!=NULL) *(p+1)='\0';
232    buf[ret]='\0';
233
234    if (buf[0] != '/')
235    {
236      strcpy(exec, link);
237      strcat(exec, buf);
238    }
239    else
240    {
241      strcpy(exec, buf);
242    }
243
244    return exec;
245  }
246  return link;
247}
248#endif /* HAVE_READLINK */
249
250#else
251
252char* omFindExec (const char *name, char* exec)
253{
254  return name;
255}
256
257#endif /* defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Note: See TracBrowser for help on using the repository browser.