mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* dln_find.c: split from dln.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26746 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5fe5eb264d
commit
9afa9ba967
5 changed files with 317 additions and 239 deletions
|
@ -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
|
||||
|
|
|
@ -34,6 +34,7 @@ COMMONOBJS = array.$(OBJEXT) \
|
|||
compar.$(OBJEXT) \
|
||||
complex.$(OBJEXT) \
|
||||
dir.$(OBJEXT) \
|
||||
dln_find.$(OBJEXT) \
|
||||
enum.$(OBJEXT) \
|
||||
enumerator.$(OBJEXT) \
|
||||
error.$(OBJEXT) \
|
||||
|
@ -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) \
|
||||
|
|
237
dln.c
237
dln.c
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
304
dln_find.c
Normal file
304
dln_find.c
Normal file
|
@ -0,0 +1,304 @@
|
|||
/**********************************************************************
|
||||
|
||||
dln.c -
|
||||
|
||||
$Author$
|
||||
created at: Tue Jan 18 17:05:06 JST 1994
|
||||
|
||||
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifdef RUBY_EXPORT
|
||||
#include "ruby/ruby.h"
|
||||
#define dln_notimplement rb_notimplement
|
||||
#define dln_memerror rb_memerror
|
||||
#define dln_exit rb_exit
|
||||
#define dln_loaderror rb_loaderror
|
||||
#else
|
||||
#define dln_notimplement --->>> dln not implemented <<<---
|
||||
#define dln_memerror abort
|
||||
#define dln_exit exit
|
||||
static void dln_loaderror(const char *format, ...);
|
||||
#endif
|
||||
#include "dln.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_DLN_A_OUT
|
||||
char *dln_argv0;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ALLOCA_H)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifndef xmalloc
|
||||
void *xmalloc();
|
||||
void *xcalloc();
|
||||
void *xrealloc();
|
||||
#endif
|
||||
|
||||
#define free(x) xfree(x)
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(_WIN32)
|
||||
#include "missing/file.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#ifndef MAXPATHLEN
|
||||
# define MAXPATHLEN 1024
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
char *getenv();
|
||||
#endif
|
||||
|
||||
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 */
|
||||
}
|
||||
}
|
9
dmydln.c
9
dmydln.c
|
@ -1,2 +1,7 @@
|
|||
#define NO_DLN_LOAD 1
|
||||
#include "dln.c"
|
||||
#include "ruby/ruby.h"
|
||||
|
||||
void*
|
||||
dln_load(const char *file)
|
||||
{
|
||||
rb_loaderror("this executable file can't load extension libraries");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue