+/* -*- mode: C; c-basic-offset: 3; -*- */
/*--------------------------------------------------------------------*/
/*--- User-mode execve() for #! scripts. m_ume_script.c ---*/
#include "priv_ume.h"
+/* Return true, if the first line begins with #! and contains an
+ interpreter. */
Bool VG_(match_script)(const void *hdr, SizeT len)
{
const HChar* script = hdr;
const HChar* end = script + len;
const HChar* interp = script + 2;
- // len < 4: need '#', '!', plus at least a '/' and one more char
- if (len < 4) return False;
+ if (len < 2) return False;
if (0 != VG_(memcmp)(hdr, "#!", 2)) return False;
- // Find interpreter name, make sure it's an absolute path (starts with
- // '/') and has at least one more char. First, skip over any space
- // between the #! and the start of the interpreter name
+ // Find interpreter name, which may be absolute or relative.
+ // First, skip over any space between the #! and the start of the
+ // interpreter name
while (interp < end && (*interp == ' ' || *interp == '\t')) interp++;
// overrun?
if (interp >= end) return False; // can't find start of interp name
- // interp should now point at the /
- if (*interp != '/') return False; // absolute path only for interpreter
-
- // check for something plausible after the /
- interp++;
- if (interp >= end) return False;
- if (VG_(isspace)(*interp)) return False;
-
- // Here we should get the full interpreter name and check it with
- // check_executable(). See the "EXEC FAILED" failure when running shell
- // for an example.
+ // No interpreter found.
+ if (*interp == '\n') return False;
return True; // looks like a #! script
}
while (interp < end && (*interp == ' ' || *interp == '\t'))
interp++;
- vg_assert(*interp == '/'); /* absolute path only for interpreter */
-
/* skip over interpreter name */
for (cp = interp; cp < end && !VG_(isspace)(*cp); cp++)
;
filter_stderr
EXTRA_DIST = \
+ say-hello.helper \
bug231357.vgtest bug231357.stderr.exp bug231357.stdout.exp \
+ bug338606.vgtest bug338606.stderr.exp \
shell shell.vgtest shell.stderr.exp shell.stderr.exp-dash \
shell.stdout.exp shell.stderr.exp-dash2 shell.stderr.exp-illumos \
shell.stderr.exp-solaris shell.stderr.exp-solaris-spawn \
shell_nointerp3.stdout.exp \
shell_nonexec.vgtest shell_nonexec.stderr.exp \
shell_nosuchfile.vgtest shell_nosuchfile.stderr.exp \
+ relative1 relative1.vgtest relative1.stderr.exp relative1.stdout.exp \
+ relative2 relative2.vgtest relative2.stderr.exp relative2.stdout.exp \
shell_valid1 shell_valid1.vgtest shell_valid1.stderr.exp \
shell_valid4 shell_valid4.vgtest shell_valid4.stderr.exp \
shell_valid4.stdout.exp \