diff --git a/repos/ports/include/noux_session/sysio.h b/repos/ports/include/noux_session/sysio.h index b6e32819b..2e71c3050 100644 --- a/repos/ports/include/noux_session/sysio.h +++ b/repos/ports/include/noux_session/sysio.h @@ -319,7 +319,9 @@ struct Noux::Sysio SYMLINK_ERR_NO_SPACE, SYMLINK_ERR_NO_PERM, SYMLINK_ERR_NAME_TOO_LONG }; - enum Execve_error { EXECVE_NONEXISTENT = Vfs::Directory_service::NUM_GENERAL_ERRORS, EXECVE_NOMEM }; + enum Execve_error { EXECVE_NONEXISTENT = Vfs::Directory_service::NUM_GENERAL_ERRORS, + EXECVE_NOMEM, + EXECVE_NOEXEC }; enum Fork_error { FORK_NOMEM = Vfs::Directory_service::NUM_GENERAL_ERRORS }; enum Select_error { SELECT_ERR_INTERRUPT }; diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index 17c499bba..1dd7ba02f 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -1101,6 +1101,7 @@ namespace { switch (sysio()->error.execve) { case Noux::Sysio::EXECVE_NONEXISTENT: errno = ENOENT; break; case Noux::Sysio::EXECVE_NOMEM: errno = ENOMEM; break; + case Noux::Sysio::EXECVE_NOEXEC: errno = ENOEXEC; break; } return -1; } diff --git a/repos/ports/src/noux/syscall.cc b/repos/ports/src/noux/syscall.cc index f81272b22..562bfe5cc 100644 --- a/repos/ports/src/noux/syscall.cc +++ b/repos/ports/src/noux/syscall.cc @@ -296,6 +296,18 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) break; } + { + Attached_dataspace attached_binary_ds(_env.rm(), binary_ds->ds); + char const *binary_addr = attached_binary_ds.local_addr(); + if ((binary_addr[0] != 0x7f) || + (binary_addr[1] != 'E') || + (binary_addr[2] != 'L') || + (binary_addr[3] != 'F')) { + _sysio.error.execve = Sysio::EXECVE_NOEXEC; + break; + } + } + binary_ds.destruct(); try {