summaryrefslogtreecommitdiff
path: root/dln.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-20 09:28:29 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-20 09:28:29 +0000
commit7ac32d7a16734ea66de15319bcff2fd429abae7f (patch)
treee11ea80c5f938e580fdf12c891c72f2aef7a9a0f /dln.c
parent3eb9283504351d9b47d5562b5ee29e2fbeb0b094 (diff)
* 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/trunk@20892 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 bb64c52..d3408fb 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");