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:
struct Binary_does_not_exist : Exception { };
/**
* Constructor
*
@ -261,6 +263,11 @@ namespace Noux {
* an executable binary (i.e., the init process,
* or children created via execve, or
* 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,
Family_member *parent,
@ -304,6 +311,11 @@ namespace Noux {
{
_env.pwd(pwd);
_args.dump();
if (!forked && !_binary_ds.valid()) {
PERR("Lookup of executable \"%s\" failed", name);
throw Binary_does_not_exist();
}
}
~Child()

View File

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