typedef struct {
- Bool (*match_fn)(const void *hdr, Int len);
+ Bool (*match_fn)(const void *hdr, SizeT len);
Int (*load_fn)(Int fd, const HChar *name, ExeInfo *info);
} ExeHandler;
Int fd, ret, i;
SysRes res;
Char buf[4096];
- SizeT bufsz = 4096, fsz;
+ SizeT bufsz = sizeof buf, fsz;
Bool is_setuid = False;
// Check it's readable
// returns: 0 = success, non-0 is failure
//
// We can execute only binaries (ELF, etc) or scripts that begin with "#!".
-// (Not, for example, scripts that don't begin with "#!"; see the
-// VG_(do_exec)() invocation from m_main.c for how that's handled.)
+// (Not, for example, scripts that don't begin with "#!"; see
+// do_exec_shell_followup for how that's handled.)
Int VG_(do_exec_inner)(const HChar* exe, ExeInfo* info)
{
SysRes res;
} else if (0 != ret) {
// Something else went wrong. Try to make the error more specific,
// and then print a message and abort.
-
- // Was it a directory?
+ Int exit_code = 126; // 126 == NOEXEC (bash)
+
res = VG_(stat)(exe_name, &st);
- if (!sr_isError(res) && VKI_S_ISDIR(st.mode)) {
+
+ // Does the file exist ?
+ if (sr_isError(res) && sr_Err(res) == VKI_ENOENT) {
+ VG_(fmsg)("%s: %s\n", exe_name, VG_(strerror)(ret));
+ exit_code = 127; // 127 == NOTFOUND (bash)
+
+ // Was it a directory?
+ } else if (!sr_isError(res) && VKI_S_ISDIR(st.mode)) {
VG_(fmsg)("%s: is a directory\n", exe_name);
// Was it not executable?
} else {
VG_(fmsg)("%s: %s\n", exe_name, VG_(strerror)(ret));
}
- // 126 means NOEXEC; I think this is Posix, and that in some cases we
- // should be returning 127, meaning NOTFOUND. Oh well.
- VG_(exit)(126);
+ VG_(exit)(exit_code);
}
return ret;
}
// This emulates the kernel's exec(). If it fails, it then emulates the
// shell's handling of the situation.
-// See ume.h for an indication of which entries of 'info' are inputs, which
-// are outputs, and which are both.
+// See pub_core_ume.h for an indication of which entries of 'info' are
+// inputs, which are outputs, and which are both.
/* returns: 0 = success, non-0 is failure */
Int VG_(do_exec)(const HChar* exe_name, ExeInfo* info)
{
#include "pub_core_ume.h" // ExeInfo
-extern int VG_(do_exec_inner)(const HChar *exe, ExeInfo *info);
+extern Int VG_(do_exec_inner)(const HChar *exe, ExeInfo *info);
#if defined(VGO_linux)
-extern Bool VG_(match_ELF) ( const void *hdr, Int len );
+extern Bool VG_(match_ELF) ( const void *hdr, SizeT len );
extern Int VG_(load_ELF) ( Int fd, const HChar *name, ExeInfo *info );
#elif defined(VGO_darwin)
-extern Bool VG_(match_macho) ( const void *hdr, Int len );
+extern Bool VG_(match_macho) ( const void *hdr, SizeT len );
extern Int VG_(load_macho) ( Int fd, const HChar *name, ExeInfo *info );
#else
# error Unknown OS
#endif
-extern Bool VG_(match_script) ( const void *hdr, Int len );
+extern Bool VG_(match_script) ( const void *hdr, SizeT len );
extern Int VG_(load_script) ( Int fd, const HChar *name, ExeInfo *info );
#include "pub_core_libcassert.h" // VG_(exit), vg_assert
#include "pub_core_libcfile.h" // VG_(close) et al
#include "pub_core_libcprint.h"
-#include "pub_core_xarray.h"
-#include "pub_core_clientstate.h"
+#include "pub_core_clientstate.h" // VG_(args_the_exename)
#include "pub_core_mallocfree.h" // VG_(strdup)
#include "pub_core_ume.h" // self
#include "priv_ume.h"
-Bool VG_(match_script)(const void *hdr, Int len)
+Bool VG_(match_script)(const void *hdr, SizeT len)
{
const HChar* script = hdr;
const HChar* end = script + len;
Int VG_(load_script)(Int fd, const HChar* name, ExeInfo* info)
{
HChar hdr[4096];
- Int len = 4096;
+ Int len = sizeof hdr;
Int eol;
HChar* interp;
HChar* end;
end = hdr + len;
interp = hdr + 2;
- while (interp < end && VG_(isspace)(*interp))
+ while (interp < end && (*interp == ' ' || *interp == '\t'))
interp++;
vg_assert(*interp == '/'); /* absolute path only for interpreter */