/* additional extensions to try in each dir if scriptname not found */
#ifdef SEARCH_EXTS
char *ext[] = { SEARCH_EXTS };
- int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
+ int extidx = 0, i = 0;
+ char *curext = Nullch;
#else
# define MAX_EXT_LEN 0
#endif
+ /*
+ * If dosearch is true and if scriptname does not contain path
+ * delimiters, search the PATH for scriptname.
+ *
+ * If SEARCH_EXTS is also defined, will look for each
+ * scriptname{SEARCH_EXTS} whenever scriptname is not found
+ * while searching the PATH.
+ *
+ * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search
+ * proceeds as follows:
+ * If DOSISH:
+ * + look for ./scriptname{,.foo,.bar}
+ * + search the PATH for scriptname{,.foo,.bar}
+ *
+ * If !DOSISH:
+ * + look *only* in the PATH for scriptname{,.foo,.bar} (note
+ * this will not look in '.' if it's not in the PATH)
+ */
+
#ifdef VMS
if (dosearch) {
int hasdir, idx = 0, deftypes = 1;
continue; /* don't search dir with too-long name */
strcat(tokenbuf, scriptname);
#else /* !VMS */
+
+#ifdef DOSISH
+ if (strEQ(scriptname, "-"))
+ dosearch = 0;
+ if (dosearch) { /* Look in '.' first. */
+ char *cur = scriptname;
+#ifdef SEARCH_EXTS
+ if ((curext = strrchr(scriptname,'.'))) /* possible current ext */
+ while (ext[i])
+ if (strEQ(ext[i++],curext)) {
+ extidx = -1; /* already has an ext */
+ break;
+ }
+ do {
+#endif
+ DEBUG_p(PerlIO_printf(Perl_debug_log,
+ "Looking for %s\n",cur));
+ if (Stat(cur,&statbuf) >= 0) {
+ dosearch = 0;
+ scriptname = cur;
+ break;
+ }
+#ifdef SEARCH_EXTS
+ if (cur == scriptname) {
+ len = strlen(scriptname);
+ if (len+MAX_EXT_LEN+1 >= sizeof(tokenbuf))
+ break;
+ cur = strcpy(tokenbuf, scriptname);
+ }
+ } while (extidx >= 0 && ext[extidx] /* try an extension? */
+ && strcpy(tokenbuf+len, ext[extidx++]));
+#endif
+ }
+#endif
if (dosearch && !strchr(scriptname, '/')
#ifdef DOSISH
&& !strchr(scriptname, '\\')
#endif
&& (s = getenv("PATH"))) {
+ bool seen_dot = 0;
+
bufend = s + strlen(s);
while (s < bufend) {
-#ifndef atarist
- s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend,
-#ifdef DOSISH
- ';',
-#else
- ':',
-#endif
- &len);
-#else /* atarist */
- for (len = 0; *s && *s != ',' && *s != ';'; len++, s++) {
+#if defined(atarist) || defined(DOSISH)
+ for (len = 0; *s
+# ifdef atarist
+ && *s != ','
+# endif
+ && *s != ';'; len++, s++) {
if (len < sizeof tokenbuf)
tokenbuf[len] = *s;
}
if (len < sizeof tokenbuf)
tokenbuf[len] = '\0';
-#endif /* atarist */
+#else /* ! (atarist || DOSISH) */
+ s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend
+ ':',
+ &len);
+#endif /* ! (atarist || DOSISH) */
if (s < bufend)
s++;
if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tokenbuf)
continue; /* don't search dir with too-long name */
if (len
-#if defined(atarist) && !defined(DOSISH)
- && tokenbuf[len - 1] != '/'
-#endif
#if defined(atarist) || defined(DOSISH)
+ && tokenbuf[len - 1] != '/'
&& tokenbuf[len - 1] != '\\'
#endif
)
tokenbuf[len++] = '/';
+ if (len == 2 && tokenbuf[0] == '.')
+ seen_dot = 1;
(void)strcpy(tokenbuf + len, scriptname);
#endif /* !VMS */
if (!xfailed)
xfailed = savepv(tokenbuf);
}
+#ifndef DOSISH
+ if (!xfound && !seen_dot && !xfailed && (Stat(scriptname,&statbuf) < 0))
+#endif
+ seen_dot = 1; /* Disable message. */
if (!xfound)
- croak("Can't execute %s", xfailed ? xfailed : scriptname );
+ croak("Can't %s %s%s%s",
+ (xfailed ? "execute" : "find"),
+ (xfailed ? xfailed : scriptname),
+ (xfailed ? "" : " on PATH"),
+ (xfailed || seen_dot) ? "" : ", '.' not in PATH");
if (xfailed)
Safefree(xfailed);
scriptname = xfound;
=item B<-S>
makes Perl use the PATH environment variable to search for the
-script (unless the name of the script starts with a slash). Typically
-this is used to emulate #! startup on machines that don't support #!,
-in the following manner:
+script (unless the name of the script contains directory separators).
+On some platforms, this also makes Perl append suffixes to the
+filename while searching for it. For example, on Win32 platforms,
+the ".bat" and ".cmd" suffixes are appended if a lookup for the
+original name fails, and if the name does not already end in one
+of those suffixes. If your Perl was compiled with DEBUGGING turned
+on, using the -Dp switch to Perl shows how the search progresses.
+
+If the file supplied contains directory separators (i.e. it is an
+absolute or relative pathname), and if the file is not found,
+platforms that append file extensions will do so and try to look
+for the file with those extensions added, one by one.
+
+On DOS-like platforms, if the script does not contain directory
+separators, it will first be searched for in the current directory
+before being searched for on the PATH. On Unix platforms, the
+script will be searched for strictly on the PATH.
+
+Typically this is used to emulate #! startup on platforms that
+don't support #!. This example works on many platforms that
+have a shell compatible with Bourne shell:
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'