source: git/resources/omFindExec.c @ 929860

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