summaryrefslogtreecommitdiff
path: root/dln.c
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-21 05:27:20 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-21 05:27:20 +0000
commit1bfa299015426d6f7d11ed169b485adb64e94b0c (patch)
treee538b010b625f444a99101865c0224c3aeea9755 /dln.c
parentdc5776d8d1ea6de34b172bec2b859c0ca991914f (diff)
merges r20892 from trunk into ruby_1_9_1.
* dln.c (dln_find_1): supplements an extension for executable files on DOSish platforms. * io.c (pipe_open): use rb_w32_aspawn() for array form. * win32/win32.c (rb_w32_pipe_exec): no longer used. * win32/win32.c (rb_w32_spawn, rb_w32_aspawn): deals with batch files and commands with extensions. [ruby-core:20695] * win32/win32.c (has_redirection): supports environment variables references. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@20899 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'dln.c')
-rw-r--r--dln.c63
1 files changed, 53 insertions, 10 deletions
diff --git a/dln.c b/dln.c
index bb64c52a0f..d3408fb0f6 100644
--- a/dln.c
+++ b/dln.c
@@ -1518,28 +1518,70 @@ dln_find_1(const char *fname, const char *path, char *fbuf, int size,
register const char *ep;
register char *bp;
struct stat st;
+ int i, fspace;
+#ifdef DOSISH
+ int is_abs = 0, has_path = 0, has_ext = 0;
+ const char *p = fname;
+#endif
#define RETURN_IF(expr) if (expr) return (char *)fname;
RETURN_IF(!fname);
- RETURN_IF(fname[0] == '/');
- RETURN_IF(strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0);
- RETURN_IF(exe_flag && strchr(fname, '/'));
#ifdef DOSISH
- RETURN_IF(fname[0] == '\\');
+# ifndef CharNext
+# define CharNext(p) ((p)+1)
+# endif
# ifdef DOSISH_DRIVE_LETTER
- RETURN_IF(strlen(fname) > 2 && fname[1] == ':');
+ if (((p[0] | 0x20) - 'a') < 26 && p[1] == ':') {
+ p += 2;
+ is_abs = 1;
+ }
# endif
- RETURN_IF(strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0);
- RETURN_IF(exe_flag && strchr(fname, '\\'));
+ switch (*p) {
+ case '/': case '\\':
+ is_abs = 1;
+ p++;
+ }
+ has_path = is_abs;
+ while (*p) {
+ switch (*p) {
+ case '/': case '\\':
+ has_path = 1;
+ has_ext = 0;
+ p++;
+ break;
+ case '.':
+ has_ext = 1;
+ p++;
+ break;
+ default:
+ p = CharNext(p);
+ }
+ }
+ ep = bp = 0;
+ if (!exe_flag) {
+ RETURN_IF(is_abs);
+ }
+ else if (has_path) {
+ RETURN_IF(has_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;
/* extract a component */
ep = strchr(dp, PATH_SEP[0]);
@@ -1602,7 +1644,7 @@ dln_find_1(const char *fname, const char *path, char *fbuf, int size,
memcpy(bp, fname, i + 1);
#if defined(DOSISH)
- if (exe_flag) {
+ if (exe_flag && !has_ext) {
static const char extension[][5] = {
#if defined(__EMX__) || defined(_WIN32)
".exe", ".com", ".cmd", ".bat",
@@ -1611,6 +1653,7 @@ dln_find_1(const char *fname, const char *path, char *fbuf, int size,
};
int j;
+ 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");