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

fieker-DuValspielwiese
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
RevLine 
[e70e45]1/*******************************************************************
2 *  File:    omFindExec.c
3 *  Purpose: routine which determines absolute pathname of executable
4 *  Author:  obachman (Olaf Bachmann)
5 *  Created: 11/99
[564ada]6 *  Version: $Id: omFindExec.c,v 1.11 2008-02-03 20:03:14 wienand Exp $
[e70e45]7 *******************************************************************/
8
[b98efa]9#ifdef HAVE_CONFIG_H
[e70e45]10#include "omConfig.h"
[b98efa]11#endif
[e70e45]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>
[4fc79f1]19#include <string.h>
[e70e45]20
[b98efa]21#include "omFindExec.h"
22
[e70e45]23#ifndef MAXPATHLEN
24#define MAXPATHLEN 1024
25#endif
26
[fa2a43]27#ifdef WINNT
28#include "om_Alloc.h"
29#endif
30
[e70e45]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);
[564ada]61#ifdef __CYGWIN__
62        strcat(executable, ".exe");
63#endif
[e70e45]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);
[564ada]86#ifdef __CYGWIN__
87        strcat(executable, ".exe");
88#endif
[e70e45]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);
[13fe1b]136
[e70e45]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);
[564ada]145#ifdef __CYGWIN__
146          strcat(executable, ".exe");
147#endif
[e70e45]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;
[13fe1b]171
[e70e45]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
[13fe1b]198/* similar to readlink (cf. man readlink), except that symbolic links are
[e70e45]199   followed up to MAX_LINK_LEVEL
200*/
201static int full_readlink(const char* name, char* buf, size_t bufsize)
202{
203  int ret;
[13fe1b]204
[e70e45]205  if ((ret=my_readlink(name, buf, bufsize)) > 0)
206  {
207    char buf2[MAXPATHLEN];
208    int ret2, i = 0;
[13fe1b]209
[e70e45]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}
[13fe1b]229
[d83977]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{
[13fe1b]235
[d83977]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)
[e70e45]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
[b98efa]288char* omFindExec (const char *name, char* exec)
[e70e45]289{
[b98efa]290  return name;
[e70e45]291}
292
293#endif /* ! defined(__MWERKS__) && defined(HAVE_UNISTD_H) && defined(STDC_HEADERS) */
Note: See TracBrowser for help on using the repository browser.