Noux: close all file descriptors on child exit

With this patch, when a child exits, all of its open file descriptors get
closed immediately. This is necessary to unblock the parent if it is
trying to read from a pipe (connected to the child) before calling
'wait4()'.

Fixes #357.
This commit is contained in:
Christian Prochaska 2012-09-14 16:46:51 +02:00 committed by Norman Feske
parent af58d39854
commit 55a8bae2f8
3 changed files with 20 additions and 3 deletions

View File

@ -325,7 +325,7 @@ namespace Noux {
_child_policy(name, _binary_ds, _args.cap(), _env.cap(),
_entrypoint, _local_noux_service,
_local_rm_service, _parent_services,
*this, _exit_context_cap, _resources.ram),
*this, *this, _exit_context_cap, _resources.ram),
_child(_binary_ds, _resources.ram.cap(), _resources.cpu.cap(),
_resources.rm.cap(), &_entrypoint, &_child_policy)
{

View File

@ -19,6 +19,7 @@
/* Noux includes */
#include <family_member.h>
#include <file_descriptor_registry.h>
#include <local_noux_service.h>
#include <local_rm_service.h>
@ -39,6 +40,7 @@ namespace Noux {
Local_rm_service &_local_rm_service;
Service_registry &_parent_services;
Family_member &_family_member;
File_descriptor_registry &_file_descriptor_registry;
Signal_context_capability _exit_context_cap;
Ram_session &_ref_ram_session;
@ -53,6 +55,7 @@ namespace Noux {
Local_rm_service &local_rm_service,
Service_registry &parent_services,
Family_member &family_member,
File_descriptor_registry &file_descriptor_registry,
Signal_context_capability exit_context_cap,
Ram_session &ref_ram_session)
:
@ -65,6 +68,7 @@ namespace Noux {
_local_rm_service(local_rm_service),
_parent_services(parent_services),
_family_member(family_member),
_file_descriptor_registry(file_descriptor_registry),
_exit_context_cap(exit_context_cap),
_ref_ram_session(ref_ram_session)
{ }
@ -107,6 +111,13 @@ namespace Noux {
{
PINF("child %s exited with exit value %d", _name, exit_value);
/*
* Close all open file descriptors. This is necessary to unblock
* the parent if it is trying to read from a pipe (connected to
* the child) before calling 'wait4()'.
*/
_file_descriptor_registry.flush();
_family_member.wakeup_parent(exit_value);
/* handle exit of the init process */

View File

@ -64,8 +64,7 @@ namespace Noux {
File_descriptor_registry()
{
for (unsigned i = 0; i < MAX_FILE_DESCRIPTORS; i++)
_reset_fd(i);
flush();
}
/**
@ -110,6 +109,13 @@ namespace Noux {
}
return _fds[fd].io_channel;
}
void flush()
{
/* close all file descriptors */
for (unsigned i = 0; i < MAX_FILE_DESCRIPTORS; i++)
_reset_fd(i);
}
};
}