summaryrefslogtreecommitdiff
path: root/dln.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-16 07:42:38 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-10-16 07:42:38 +0000
commit369218ed2105c24bd4c4e24a85012eafd10800a7 (patch)
treeb1bdbb2592dabf117dde05ad4eab1ea2bd4aaec1 /dln.c
parentac0b7f38fe41d9e90faa8651dcee32d2c9fe1690 (diff)
* dln.c (dln_find_1): backport from trunkn. [ruby-core:25802]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@25368 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'dln.c')
-rw-r--r--dln.c150
1 files changed, 86 insertions, 64 deletions
diff --git a/dln.c b/dln.c
index 5a2f8dfcd4..aea6e1c3f1 100644
--- a/dln.c
+++ b/dln.c
@@ -1653,6 +1653,8 @@ dln_load(file)
static char *dln_find_1();
+static char fbuf[MAXPATHLEN];
+
char *
dln_find_exe(fname, path)
const char *fname;
@@ -1669,7 +1671,7 @@ dln_find_exe(fname, path)
path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
#endif
}
- return dln_find_1(fname, path, 1);
+ return dln_find_1(fname, path, fbuf, sizeof(fbuf), 1);
}
char *
@@ -1682,45 +1684,95 @@ dln_find_file(fname, path)
return dln_find_1(fname, path, 0);
#else
if (!path) path = ".";
- return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, 0));
+ return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, fbuf, sizeof(fbuf), 0));
#endif
}
-static char fbuf[MAXPATHLEN];
-
static char *
-dln_find_1(fname, path, exe_flag)
- const char *fname;
- const char *path;
- int exe_flag; /* non 0 if looking for executable. */
+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;
-#ifdef __MACOS__
- const char* mac_fullpath;
+ size_t i, fspace;
+#ifdef DOSISH
+ static const char extension[][5] = {
+ ".exe", ".com", ".cmd", ".bat",
+ };
+ size_t j;
+ int is_abs = 0, has_path = 0;
+ const char *ext = 0;
+ const char *p = fname;
#endif
- if (!fname) return (char *)fname;
- if (fname[0] == '/') return (char *)fname;
- if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
- return (char *)fname;
- if (exe_flag && strchr(fname, '/')) return (char *)fname;
+#define RETURN_IF(expr) if (expr) return (char *)fname;
+
+ RETURN_IF(!fname);
#ifdef DOSISH
- if (fname[0] == '\\') return (char *)fname;
+# ifndef CharNext
+# define CharNext(p) ((p)+1)
+# endif
# ifdef DOSISH_DRIVE_LETTER
- if (strlen(fname) > 2 && fname[1] == ':') return (char *)fname;
+ if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') {
+ p += 2;
+ is_abs = 1;
+ }
# endif
- if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0)
- return (char *)fname;
- if (exe_flag && strchr(fname, '\\')) return (char *)fname;
+ 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;
+ }
#endif
+ RETURN_IF(fname[0] == '/');
+ RETURN_IF(strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0);
+ RETURN_IF(exe_flag && strchr(fname, '/'));
+
+#undef RETURN_IF
+
for (dp = path;; dp = ++ep) {
- register int l;
- int i;
- int fspace;
+ register size_t l;
/* extract a component */
ep = strchr(dp, PATH_SEP[0]);
@@ -1730,7 +1782,7 @@ dln_find_1(fname, path, exe_flag)
/* find the length of that component */
l = ep - dp;
bp = fbuf;
- fspace = sizeof fbuf - 2;
+ fspace = size - 2;
if (l > 0) {
/*
** If the length of the component is zero length,
@@ -1742,7 +1794,7 @@ dln_find_1(fname, path, exe_flag)
if (*dp == '~' && (l == 1 ||
#if defined(DOSISH)
- dp[1] == '\\' ||
+ dp[1] == '\\' ||
#endif
dp[1] == '/')) {
char *home;
@@ -1750,8 +1802,9 @@ dln_find_1(fname, path, exe_flag)
home = getenv("HOME");
if (home != NULL) {
i = strlen(home);
- if ((fspace -= i) < 0)
+ if (fspace < i)
goto toolong;
+ fspace -= i;
memcpy(bp, home, i);
bp += i;
}
@@ -1759,8 +1812,9 @@ dln_find_1(fname, path, exe_flag)
l--;
}
if (l > 0) {
- if ((fspace -= l) < 0)
+ if (fspace < l)
goto toolong;
+ fspace -= l;
memcpy(bp, dp, l);
bp += l;
}
@@ -1772,7 +1826,7 @@ dln_find_1(fname, path, exe_flag)
/* now append the file name */
i = strlen(fname);
- if ((fspace -= i) < 0) {
+ if (fspace < i) {
toolong:
fprintf(stderr, "openpath: pathname too long (ignored)\n");
*bp = '\0';
@@ -1780,26 +1834,12 @@ dln_find_1(fname, path, exe_flag)
fprintf(stderr, "\tFile \"%s\"\n", fname);
goto next;
}
+ fspace -= i;
memcpy(bp, fname, i + 1);
#if defined(DOSISH)
- if (exe_flag) {
- static const char extension[][5] = {
-#if defined(MSDOS)
- ".com", ".exe", ".bat",
-#if defined(DJGPP)
- ".btm", ".sh", ".ksh", ".pl", ".sed",
-#endif
-#elif defined(__EMX__) || defined(_WIN32)
- ".exe", ".com", ".cmd", ".bat",
-/* end of __EMX__ or _WIN32 */
-#else
- ".r", ".R", ".x", ".X", ".bat", ".BAT",
-/* __human68k__ */
-#endif
- };
- int j;
-
+ if (exe_flag && !ext) {
+ needs_extension:
for (j = 0; j < sizeof(extension) / sizeof(extension[0]); j++) {
if (fspace < strlen(extension[j])) {
fprintf(stderr, "openpath: pathname too long (ignored)\n");
@@ -1808,37 +1848,19 @@ dln_find_1(fname, path, exe_flag)
continue;
}
strcpy(bp + i, extension[j]);
-#ifndef __MACOS__
if (stat(fbuf, &st) == 0)
return fbuf;
-#else
- if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf))
- return mac_fullpath;
-
-#endif
}
goto next;
}
-#endif /* MSDOS or _WIN32 or __human68k__ or __EMX__ */
+#endif /* _WIN32 or __EMX__ */
-#ifndef __MACOS__
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;
}
-#else
- if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {
- if (exe_flag == 0) return mac_fullpath;
- /* looking for executable */
- if (stat(mac_fullpath, &st) == 0) {
- if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0)
- return mac_fullpath;
- }
- }
-#endif
-
next:
/* if not, and no other alternatives, life is bleak */
if (*ep == '\0') {