Skip to content

Commit

Permalink
* dln_find.c: split from dln.c.
Browse files Browse the repository at this point in the history
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26746 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
nobu committed Feb 24, 2010
1 parent 5fe5eb2 commit 9afa9ba
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 239 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
@@ -1,3 +1,7 @@
Wed Feb 24 09:54:58 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>

* dln_find.c: split from dln.c.

Wed Feb 24 09:31:33 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>

* ext/digest/extconf.rb: use OpenSSL only when all transform
Expand Down
2 changes: 2 additions & 0 deletions common.mk
Expand Up @@ -34,6 +34,7 @@ COMMONOBJS = array.$(OBJEXT) \
compar.$(OBJEXT) \
complex.$(OBJEXT) \
dir.$(OBJEXT) \
dln_find.$(OBJEXT) \
enum.$(OBJEXT) \
enumerator.$(OBJEXT) \
error.$(OBJEXT) \
Expand Down Expand Up @@ -527,6 +528,7 @@ complex.$(OBJEXT): {$(VPATH)}complex.c $(RUBY_H_INCLUDES)
dir.$(OBJEXT): {$(VPATH)}dir.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
$(ENCODING_H_INCLUDES)
dln.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES)
dln_find.$(OBJEXT): {$(VPATH)}dln.c {$(VPATH)}dln.h $(RUBY_H_INCLUDES)
dmydln.$(OBJEXT): {$(VPATH)}dmydln.c dln.$(OBJEXT)
dmyext.$(OBJEXT): {$(VPATH)}dmyext.c
dmyencoding.$(OBJEXT): {$(VPATH)}dmyencoding.c $(RUBY_H_INCLUDES) \
Expand Down
237 changes: 0 additions & 237 deletions dln.c
Expand Up @@ -100,8 +100,6 @@ dln_loaderror(const char *format, ...)
}
#endif

#ifndef NO_DLN_LOAD

#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(_AIX) && !defined(MACOSX_DYLD) && !defined(_UNICOSMP)
/* dynamic load with dlopen() */
# define USE_DLN_DLOPEN
Expand Down Expand Up @@ -1220,15 +1218,9 @@ aix_loaderror(const char *pathname)
}
#endif

#endif /* NO_DLN_LOAD */

void*
dln_load(const char *file)
{
#ifdef NO_DLN_LOAD
dln_loaderror("this executable file can't load extension libraries");
#else

#if !defined(_AIX) && !defined(NeXT)
const char *error = 0;
#define DLN_ERROR() (error = dln_strerror(), strcpy(ALLOCA_N(char, strlen(error) + 1), error))
Expand Down Expand Up @@ -1492,234 +1484,5 @@ dln_load(const char *file)
dln_loaderror("%s - %s", error, file);
#endif

#endif /* NO_DLN_LOAD */
return 0; /* dummy return */
}

static char *dln_find_1(const char *fname, const char *path, char *buf, size_t size, int exe_flag);

char *
dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size)
{
char *envpath = 0;

if (!path) {
path = getenv(PATH_ENV);
if (path) path = envpath = strdup(path);
}

if (!path) {
#if defined(_WIN32)
path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;.";
#else
path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
#endif
}
buf = dln_find_1(fname, path, buf, size, 1);
if (envpath) free(envpath);
return buf;
}

char *
dln_find_file_r(const char *fname, const char *path, char *buf, size_t size)
{
if (!path) path = ".";
return dln_find_1(fname, path, buf, size, 0);
}

static char fbuf[MAXPATHLEN];

char *
dln_find_exe(const char *fname, const char *path)
{
return dln_find_exe_r(fname, path, fbuf, sizeof(fbuf));
}

char *
dln_find_file(const char *fname, const char *path)
{
return dln_find_file_r(fname, path, fbuf, sizeof(fbuf));
}

static char *
dln_find_1(const char *fname, const char *path, char *fbuf, size_t size,
int exe_flag /* non 0 if looking for executable. */)
{
register const char *dp;
register const char *ep;
register char *bp;
struct stat st;
size_t i, fspace;
#ifdef DOSISH
static const char extension[][5] = {
EXECUTABLE_EXTS,
};
size_t j;
int is_abs = 0, has_path = 0;
const char *ext = 0;
#endif
const char *p = fname;

static const char pathname_too_long[] = "openpath: pathname too long (ignored)\n\
\tDirectory \"%.*s\"\n\tFile \"%s\"\n";
#define PATHNAME_TOO_LONG() fprintf(stderr, pathname_too_long, (int)(bp - fbuf), fbuf, fname)

#define RETURN_IF(expr) if (expr) return (char *)fname;

RETURN_IF(!fname);
#ifdef DOSISH
# ifndef CharNext
# define CharNext(p) ((p)+1)
# endif
# ifdef DOSISH_DRIVE_LETTER
if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') {
p += 2;
is_abs = 1;
}
# endif
switch (*p) {
case '/': case '\\':
is_abs = 1;
p++;
}
has_path = is_abs;
while (*p) {
switch (*p) {
case '/': case '\\':
has_path = 1;
ext = 0;
p++;
break;
case '.':
ext = p;
p++;
break;
default:
p = CharNext(p);
}
}
if (ext) {
for (j = 0; STRCASECMP(ext, extension[j]); ) {
if (++j == sizeof(extension) / sizeof(extension[0])) {
ext = 0;
break;
}
}
}
ep = bp = 0;
if (!exe_flag) {
RETURN_IF(is_abs);
}
else if (has_path) {
RETURN_IF(ext);
i = p - fname;
if (i + 1 > size) goto toolong;
fspace = size - i - 1;
bp = fbuf;
ep = p;
memcpy(fbuf, fname, i + 1);
goto needs_extension;
}
p = fname;
#endif

if (*p == '.' && *++p == '.') ++p;
RETURN_IF(*p == '/');
RETURN_IF(exe_flag && strchr(fname, '/'));

#undef RETURN_IF

for (dp = path;; dp = ++ep) {
register size_t l;

/* extract a component */
ep = strchr(dp, PATH_SEP[0]);
if (ep == NULL)
ep = dp+strlen(dp);

/* find the length of that component */
l = ep - dp;
bp = fbuf;
fspace = size - 2;
if (l > 0) {
/*
** If the length of the component is zero length,
** start from the current directory. If the
** component begins with "~", start from the
** user's $HOME environment variable. Otherwise
** take the path literally.
*/

if (*dp == '~' && (l == 1 ||
#if defined(DOSISH)
dp[1] == '\\' ||
#endif
dp[1] == '/')) {
char *home;

home = getenv("HOME");
if (home != NULL) {
i = strlen(home);
if (fspace < i)
goto toolong;
fspace -= i;
memcpy(bp, home, i);
bp += i;
}
dp++;
l--;
}
if (l > 0) {
if (fspace < l)
goto toolong;
fspace -= l;
memcpy(bp, dp, l);
bp += l;
}

/* add a "/" between directory and filename */
if (ep[-1] != '/')
*bp++ = '/';
}

/* now append the file name */
i = strlen(fname);
if (fspace < i) {
toolong:
PATHNAME_TOO_LONG();
goto next;
}
fspace -= i;
memcpy(bp, fname, i + 1);

#if defined(DOSISH)
if (exe_flag && !ext) {
needs_extension:
for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
if (fspace < strlen(extension[j])) {
PATHNAME_TOO_LONG();
continue;
}
strlcpy(bp + i, extension[j], fspace);
if (stat(fbuf, &st) == 0)
return fbuf;
}
goto next;
}
#endif /* _WIN32 or __EMX__ */

if (stat(fbuf, &st) == 0) {
if (exe_flag == 0) return fbuf;
/* looking for executable */
if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)
return fbuf;
}
next:
/* if not, and no other alternatives, life is bleak */
if (*ep == '\0') {
return NULL;
}

/* otherwise try the next component in the search path */
}
}

0 comments on commit 9afa9ba

Please sign in to comment.