Detect execve failure

This commit is contained in:
Norman Feske 2012-05-18 17:10:54 +02:00
parent cdbd1630bb
commit 0f6b59097e
2 changed files with 41 additions and 23 deletions

View File

@ -254,6 +254,8 @@ namespace Noux {
public: public:
struct Binary_does_not_exist : Exception { };
/** /**
* Constructor * Constructor
* *
@ -261,6 +263,11 @@ namespace Noux {
* an executable binary (i.e., the init process, * an executable binary (i.e., the init process,
* or children created via execve, or * or children created via execve, or
* true if the child is a fork from another child * true if the child is a fork from another child
*
* \throw Binary_does_not_exist if child is not a fork and the
* specified name could not be
* looked up at the virtual file
* system
*/ */
Child(char const *name, Child(char const *name,
Family_member *parent, Family_member *parent,
@ -304,6 +311,11 @@ namespace Noux {
{ {
_env.pwd(pwd); _env.pwd(pwd);
_args.dump(); _args.dump();
if (!forked && !_binary_ds.valid()) {
PERR("Lookup of executable \"%s\" failed", name);
throw Binary_does_not_exist();
}
} }
~Child() ~Child()

View File

@ -224,34 +224,40 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
j += strlen(src); j += strlen(src);
} }
Child *child = new Child(absolute_path.base(), try {
parent(), Child *child = new Child(absolute_path.base(),
pid(), parent(),
_sig_rec, pid(),
_root_dir, _sig_rec,
Args(_sysio->execve_in.args, _root_dir,
sizeof(_sysio->execve_in.args)), Args(_sysio->execve_in.args,
env, sizeof(_sysio->execve_in.args)),
_env.pwd(), env,
_cap_session, _env.pwd(),
_parent_services, _cap_session,
_resources.ep, _parent_services,
false); _resources.ep,
false);
/* replace ourself by the new child at the parent */ /* replace ourself by the new child at the parent */
parent()->remove(this); parent()->remove(this);
parent()->insert(child); parent()->insert(child);
_assign_io_channels_to(child); _assign_io_channels_to(child);
/* signal main thread to remove ourself */ /* signal main thread to remove ourself */
Genode::Signal_transmitter(_execve_cleanup_context_cap).submit(); Genode::Signal_transmitter(_execve_cleanup_context_cap).submit();
/* start executing the new process */ /* start executing the new process */
child->start(); child->start();
/* this child will be removed by the execve_finalization_dispatcher */ /* this child will be removed by the execve_finalization_dispatcher */
return true; return true;
}
catch (Child::Binary_does_not_exist) {
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT; }
return false;
} }
case SYSCALL_SELECT: case SYSCALL_SELECT: