source: git/omalloc/omFindExec.c @ 8627ad

spielwiese
Last change on this file since 8627ad was 564ada, checked in by Oliver Wienand <wienand@…>, 16 years ago
omFindExec: now works on Cygwin git-svn-id: file:///usr/local/Singular/svn/trunk@10552 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.0 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 *  Version: $Id: omFindExec.c,v 1.11 2008-02-03 20:03:14 wienand Exp $
7 *******************************************************************/
8
9#ifdef HAVE_CONFIG_H
10#include "omConfig.h"
11#endif
12
13#if ! defined(__MWERKS__) && defined(HAVE_UNISTD_H) && defined(STDC_HEADERS)
14
15#ifdef HAVE_UNISTD_H
16#include <unistd.h> /* always defiend */
17#endif
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#ifdef WINNT
28#include "om_Alloc.h"
29#endif
30
31/* ABSOLUTE_FILENAME_P (fname): True if fname is an absolute filename */
32#ifdef atarist
33#define ABSOLUTE_FILENAME_P(fname)        ((fname[0] == '/') || \
34        (fname[0] && (fname[1] == ':')))
35#else
36#define ABSOLUTE_FILENAME_P(fname)        (fname[0] == '/')
37#endif /* atarist */
38
39/* Return the absolute name of the program named NAME.  This function
40   searches the directories in the PATH environment variable if PROG
41   has no directory components. */
42#ifndef HAVE_READLINK
43char * omFindExec (const char *name, char* executable)
44#else
45static char * omFindExec_link (const char *name, char* executable)
46#endif
47{
48  char *search;
49  char *p;
50#ifdef WINNT
51  char *extra = NULL;
52#endif
53  char tbuf[MAXPATHLEN];
54
55  if (ABSOLUTE_FILENAME_P(name))
56  {
57      /* If we can execute the named file then return it. */
58      if (! access (name, X_OK))
59      {
60        strcpy(executable, name);
61#ifdef __CYGWIN__
62        strcat(executable, ".exe");
63#endif
64        return executable;
65      }
66  }
67  else
68  {
69    if (((name[0] == '.') && (name[1] == '/')) ||
70        ((name[0] == '.') && (name[1] == '.') && (name[2] == '/')) ||
71        strchr(name, '/') != NULL)
72    {
73
74#ifdef HAVE_GETCWD
75      getcwd (tbuf, MAXPATHLEN);
76#else
77# ifdef HAVE_GETWD
78      getwd (tbuf);
79# endif
80#endif
81      strcat (tbuf, "/");
82      strcat (tbuf, name);
83      if (! access(tbuf, X_OK))
84      {
85        strcpy(executable, tbuf);
86#ifdef __CYGWIN__
87        strcat(executable, ".exe");
88#endif
89        return executable;
90      }
91    }
92
93
94    search = getenv("PATH");
95/* for winnt under msdos, cwd is implictly in the path */
96#ifdef WINNT
97    p = getenv("SHELL");
98    if (p == NULL || strlen(p) < 2)
99    {
100      char *extra = NULL;
101      /* we are under msdos display */
102      extra = (char*) omAlloc((search != NULL ? strlen(search) : 0) + 3);
103      strcpy(extra, ".:");
104      if (search != NULL) strcat(extra, search);
105      search = extra;
106    }
107#endif
108    p = search;
109
110    if (p != NULL)
111    {
112      while (1)
113      {
114        char *next;
115        next = tbuf;
116
117        /* Copy directory name into [tbuf]. */
118        /* This is somewhat tricky: empty names mean cwd, w.r.t. some
119           shell spec */
120        while (*p && *p != ':')
121          *next ++ = *p ++;
122        *next = '\0';
123
124        if ((tbuf[0] == '.' && tbuf[1] == '\0') || tbuf[0] == '\0') {
125#ifdef HAVE_GETCWD
126          getcwd (tbuf, MAXPATHLEN);
127#else
128# ifdef HAVE_GETWD
129          getwd (tbuf);
130# endif
131#endif
132        }
133
134        if (tbuf[strlen(tbuf)-1] != '/') strcat(tbuf, "/");
135        strcat (tbuf, name);
136
137        /* If we can execute the named file, then return it. */
138        if (! access (tbuf, X_OK))
139        {
140#ifdef WINNT
141          if (extra != NULL)
142            omFree(extra);
143#endif
144          strcpy(executable, tbuf);
145#ifdef __CYGWIN__
146          strcat(executable, ".exe");
147#endif
148          return executable;
149        }
150
151        if (*p != '\0')
152        {
153          p ++;
154        }
155        else
156        {
157          break;
158        }
159      }
160    }
161  }
162  return NULL;
163}
164
165#ifdef HAVE_READLINK
166/* similar to readlink, but dont' mess up absolute pathnames */
167static int my_readlink(const char* name, char* buf, size_t bufsize)
168{
169  char buf2[MAXPATHLEN];
170  int ret;
171
172  if ((ret = readlink(name, buf2, bufsize)) > 0)
173  {
174    buf2[ret] = 0;
175    if (*name == '/' && *buf2 != '/')
176    {
177      char* last = strrchr(name, '/');
178      int i = 0;
179      while (&(name[i]) != last)
180      {
181        buf[i] = name[i];
182        i++;
183      }
184      buf[i] = '/';
185      i++;
186      strcpy(&(buf[i]), buf2);
187      return i + ret;
188    }
189    else
190    {
191      strcpy(buf, buf2);
192    }
193  }
194  return ret;
195}
196
197#define MAX_LINK_LEVEL 10
198/* similar to readlink (cf. man readlink), except that symbolic links are
199   followed up to MAX_LINK_LEVEL
200*/
201static int full_readlink(const char* name, char* buf, size_t bufsize)
202{
203  int ret;
204
205  if ((ret=my_readlink(name, buf, bufsize)) > 0)
206  {
207    char buf2[MAXPATHLEN];
208    int ret2, i = 0;
209
210    do
211    {
212      buf[ret] = '\0';
213      if ((ret2 = my_readlink(buf, buf2, MAXPATHLEN)) > 0)
214      {
215        i++;
216        buf2[ret2] = '\0';
217        strcpy(buf, buf2);
218        ret = ret2;
219      }
220      else
221      {
222        return ret;
223      }
224    }
225    while (i<MAX_LINK_LEVEL);
226  }
227  return -1;
228}
229
230#ifdef WINNT
231char * _omFindExec (const char *name, char* exec);
232/* for windows, serch first for .exe */
233char* omFindExec(const char *name, char* exec)
234{
235
236  if (strstr(name, ".exe") == NULL)
237  {
238    char buf[MAXPATHLEN];
239    char* ret;
240    strcpy(buf, name);
241    strcat(buf, ".exe");
242    ret = _omFindExec(buf, exec);
243    if (ret != NULL) return ret;
244  }
245  return _omFindExec(name, exec);
246}
247#else
248#define _omFindExec omFindExec
249#endif
250
251char * _omFindExec (const char *name, char* exec)
252{
253  char * link = omFindExec_link(name, exec);
254  char buf[MAXPATHLEN];
255  int ret;
256
257  if (link == NULL && (ret=full_readlink(name, buf, MAXPATHLEN)) > 0)
258  {
259    buf[ret] ='\0';
260    link = omFindExec_link(buf, exec);
261  }
262  if (link != NULL && (ret=full_readlink(link, buf, MAXPATHLEN)) > 0)
263  {
264    char *p = strrchr(link, '/');
265
266
267    if(p!=NULL) *(p+1)='\0';
268    buf[ret]='\0';
269
270    if (buf[0] != '/')
271    {
272      strcpy(exec, link);
273      strcat(exec, buf);
274    }
275    else
276    {
277      strcpy(exec, buf);
278    }
279
280    return exec;
281  }
282  return link;
283}
284#endif /* HAVE_READLINK */
285
286#else
287
288char* omFindExec (const char *name, char* exec)
289{
290  return name;
291}
292
293#endif /* ! defined(__MWERKS__) && defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Note: See TracBrowser for help on using the repository browser.