#include "config.h"
#include "server-Vfs.h" /* self */
-#include "server-GlibLogFunc.h" /* for impl_Captive_Vfs_registerGlibLogFunc() */
#include "sandbox.h"
#include <glib/gmessages.h>
#include "captive/macros.h"
#include "server-Directory.h"
#include "server-File.h"
#include "split.h"
+#include "server-GLogFunc.h"
+#include "client-CaptiveIOChannel.h"
+static void impl_Captive_Vfs_fini(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev);
+static void impl_Captive_Vfs_init
+ (impl_POA_Captive_Vfs *servant,const Captive_CaptiveOptions *options_corba,CORBA_Environment *ev);
static void impl_Captive_Vfs_shutdown(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev);
static PortableServer_ServantBase__epv impl_Captive_Vfs_base_epv={
NULL, /* _private data */
- NULL, /* finalize routine */
+ (gpointer)&impl_Captive_Vfs_fini, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_Captive_Vfs__epv impl_Captive_Vfs_epv={
NULL, /* _private */
- (gpointer)&impl_Captive_Vfs_registerGlibLogFunc,
+ (gpointer)&impl_Captive_Vfs_init,
(gpointer)&impl_Captive_Vfs_shutdown,
(gpointer)&impl_Captive_Vfs_directory_new_open,
(gpointer)&impl_Captive_Vfs_directory_new_make,
};
-struct captive_options *captive_corba_child_options;
-
-
Captive_Vfs impl_Captive_Vfs__create(PortableServer_POA poa,CORBA_Environment *ev)
{
Captive_Vfs retval;
impl_POA_Captive_Vfs *newservant;
PortableServer_ObjectId *objid;
-GnomeVFSResult errvfsresult;
captive_new0(newservant); /* FIXME: leak */
newservant->servant.vepv=&impl_Captive_Vfs_vepv;
newservant->poa=poa;
- if (GNOME_VFS_OK!=(errvfsresult=captive_vfs_new(&newservant->captive_vfs_object,captive_corba_child_options))) {
- g_free(newservant);
- CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_Captive_GnomeVFSResultException,GINT_TO_POINTER((gint)errvfsresult));
- return NULL;
- }
+ newservant->captive_vfs_object=NULL;
POA_Captive_Vfs__init((PortableServer_Servant)newservant,ev);
objid=PortableServer_POA_activate_object(poa,newservant,ev);
CORBA_free(objid);
}
+static void impl_Captive_Vfs_fini(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev)
+{
+ if (servant->captive_vfs_object) {
+ g_object_unref(servant->captive_vfs_object);
+ servant->captive_vfs_object=NULL;
+ }
+}
+
+
+static Captive_CaptiveIOChannel options_corba_image_iochannel_copy;
+
+void impl_Captive_Vfs__destroy(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev)
+{
+PortableServer_ObjectId *objid;
+
+ objid=PortableServer_POA_servant_to_id(servant->poa,servant,ev);
+ PortableServer_POA_deactivate_object(servant->poa,objid,ev);
+ CORBA_free(objid);
+ impl_Captive_Vfs_fini(servant,ev);
+ CORBA_Object_release(options_corba_image_iochannel_copy,ev);
+ g_free(servant);
+}
+
+
+static void options_module_corba_to_options_module_captive
+ (struct captive_options_module *dest_options_module_captive,const Captive_CaptiveOptionsModule *src_options_module_corba)
+{
+ g_return_if_fail(dest_options_module_captive!=NULL);
+ g_return_if_fail(src_options_module_corba!=NULL);
+
+ dest_options_module_captive->pathname_utf8=g_strdup(src_options_module_corba->pathname_utf8);
+ dest_options_module_captive->type=CAPTIVE_OPTIONS_MODULE_TYPE_PE32;
+ dest_options_module_captive->u.pe32.base=g_memdup(src_options_module_corba->data._buffer,
+ src_options_module_corba->data._length);
+ dest_options_module_captive->u.pe32.length=src_options_module_corba->data._length;
+ dest_options_module_captive->u.pe32.mapped=FALSE;
+}
+
+
+static void impl_Captive_Vfs_init
+ (impl_POA_Captive_Vfs *servant,const Captive_CaptiveOptions *options_corba,CORBA_Environment *ev)
+{
+struct captive_options options_captive;
+GnomeVFSResult errvfsresult;
+guint moduleui;
+
+ g_return_if_fail(servant->captive_vfs_object==NULL);
+
+ options_corba_image_iochannel_copy=CORBA_Object_duplicate(options_corba->image_iochannel,ev);
+ if (ev->_major!=CORBA_NO_EXCEPTION)
+ return;
+
+ /* impl_Captive_Vfs_init_g_log_func() does its own copy of 'options_corba->g_log_func'. */
+ impl_Captive_Vfs_init_g_log_func(options_corba->g_log_func,options_corba->debug_messages,ev);
+
+ captive_options_init(&options_captive);
+
+ options_module_corba_to_options_module_captive(&options_captive.filesystem,&options_corba->filesystem);
+
+ options_captive.debug_messages=options_corba->debug_messages;
+ options_captive.rwmode =options_corba->rwmode;
+ options_captive.media =options_corba->media;
+
+ options_captive.image_iochannel=(GIOChannel *)captive_io_channel_new(
+ options_corba_image_iochannel_copy, /* corba_captive_io_channel */
+ (options_captive.rwmode!=CAPTIVE_OPTION_RWMODE_RO)); /* writeable */
+
+ for (moduleui=0;moduleui<options_corba->load_module._length;moduleui++) {
+struct captive_options_module *options_module;
+
+ captive_new(options_module);
+ options_module_corba_to_options_module_captive(options_module,options_corba->load_module._buffer+moduleui);
+ options_captive.load_module=g_list_append(options_captive.load_module,options_module);
+ }
+
+ g_assert(captive_sandbox_server_argv==NULL);
+
+ if (GNOME_VFS_OK!=(errvfsresult=captive_vfs_new(&servant->captive_vfs_object,&options_captive))) {
+ CORBA_exception_set(ev,CORBA_USER_EXCEPTION,ex_Captive_GnomeVFSResultException,GINT_TO_POINTER((gint)errvfsresult));
+ captive_options_free(&options_captive);
+ return;
+ }
+
+ captive_options_free(&options_captive);
+
+ g_assert(servant->captive_vfs_object!=NULL);
+}
+
+
static gboolean impl_Captive_Vfs_shutdown_idle(gpointer data /* unused */)
{
sandbox_child_shutdown();
static void impl_Captive_Vfs_shutdown(impl_POA_Captive_Vfs *servant,CORBA_Environment *ev)
{
+GSource *source;
+
+ /* Shutdown 'servant->captive_vfs_object' synchronously as it may
+ * flush its buffers needed to be transferred to our parent.
+ */
+ impl_Captive_Vfs_fini(servant,&captive_corba_ev);
+ g_assert(validate_CORBA_Environment(&captive_corba_ev));
+
+ sandbox_child_prepare_shutdown();
+
/* Do not call sandbox_child_shutdown() directly as we would fail
* to finish this CORBA method call properly.
+ * Do not call g_idle_add_full() as it would miss linc main loop.
*/
- g_idle_add_full(
- G_PRIORITY_LOW, /* priority */
- impl_Captive_Vfs_shutdown_idle, /* function */
- NULL, /* data */
+ source=g_idle_source_new ();
+ g_source_set_priority(source,G_PRIORITY_LOW);
+ g_source_set_callback(
+ source, /* source */
+ (GSourceFunc)impl_Captive_Vfs_shutdown_idle, /* func */
+ servant, /* data */
NULL); /* notify */
+ g_source_attach(source,
+ g_main_loop_get_context(linc_main_get_loop())); /* context; NULL means 'default context' */
+ g_source_unref(source);
}