Example 5-32. name-resolve.idl
module Examples {
module NameResolve {
interface Service {
void echoString (in string input);
};
};
};
| File | Usage for Client | Usage for Server |
|---|---|---|
| name-resolve.h | readonly | readonly |
| name-resolve-common.c | readonly | readonly |
| name-resolve-stubs.c | readonly | - |
| name-resolve-skels.c | - | readonly |
| name-resolve-skelimpl.c | - | template for user code |
| name-resolve-client.c | write the client code |
| name-resolve-server.c | write the generic code for servant creation |
Example 5-33. example-toolkit.c(etk_get_name_service)
/** resolves default name-service, usually given to application as
* command line argument "-ORBInitRef NameService=IOR:0100000028..",
* or since release 2.8.0 corbalocs in form of URL can be used, eg:
* "-ORBInitRef NameService=corbaloc:iiop:HOSTNAME:PORT/NameService%00"
*/
CosNaming_NamingContext
etk_get_name_service (CORBA_ORB orb,
CORBA_Environment *ev)
{
CORBA_char *str=NULL;
CORBA_Object ref
= (CORBA_Object) CORBA_ORB_resolve_initial_references(orb,
"NameService",
ev);
if (etk_raised_exception(ev)) return CORBA_OBJECT_NIL;
return (CosNaming_NamingContext) ref;
}
Example 5-34. example-toolkit.c(etk_name_service_bind)
/** calculate length of NULL terminated string vector */
static
guint
id_vec_len (char *id_vec[])
{
gint i=0;
for (i = 0; id_vec[i]; ++i);
return i;
}
/* binds @servant object reference to unique @name at
* @name_service. @name is a NULL terminated list of strings
* (CORBA_char*). If error occures @ev points to exception object on
* return.
*/
void
etk_name_service_bind (CosNaming_NamingContext name_service,
CORBA_Object servant,
gchar *id_vec[],
CORBA_Environment *ev)
{
gint i = 0;
gint len = id_vec_len (id_vec);
/* Allocate a CosNaming::Name (sequence of CosNaming::NameComponent) */
CosNaming_Name *name = CosNaming_Name__alloc();
name->_buffer = CORBA_sequence_CosNaming_NameComponent_allocbuf(len);
name->_maximum = len;
name->_length = 0;
/* Relinquish ownership of the NameComponent to the
* sequence. When CORBA_free is called on it later, the
* NameComponent will be freed */
CORBA_sequence_set_release (name, TRUE);
/* iterate components of name and create sub-context
* (directory) if needed */
for (i = 0; i < len; ++i) {
name->_length = i+1;
name->_buffer[i].id = CORBA_string_dup(id_vec[i]);
name->_buffer[i].kind = CORBA_string_dup("");
/* don't know what 'kind' shall be good for */
if (name->_length < len)
{
/* create a sub-context */
CosNaming_NamingContext nc =
CosNaming_NamingContext_bind_new_context (name_service,
name,
ev);
if (etk_raised_exception_is_a (ev,
ex_CosNaming_NamingContext_AlreadyBound))
{
/* ignore - ctx allread exists, this
* is not dramatic */
CORBA_exception_free (ev);
}
else if (etk_raised_exception (ev))
{
/* critical - unexpected exception */
CORBA_free (name);
return;
}
}
else
{
/* Bind object to last context - use 'rebind'
* operation in case the name has been
* registered allready in context - note, this
* might interfere with other service choosing
* same name */
CosNaming_NamingContext_rebind (name_service,
name,
servant,
ev);
if (etk_raised_exception(ev)) {
/* critical - can not bind object */
CORBA_free (name);
return;
}
}
}
CORBA_free (name);
return;
}
Example 5-35. example-toolkit.c(etk_name_service_resolve)
/* resolves object reference @return with unique @name at
* @name_service. @name is a NULL terminated list of strings
* (CORBA_char*). If error occures @ev points to * exception object
* on return.
*/
CORBA_Object
etk_name_service_resolve (CosNaming_NamingContext name_service,
gchar *id_vec[],
CORBA_Environment *ev)
{
CORBA_Object retval = CORBA_OBJECT_NIL;
gint i = 0;
gint len = id_vec_len (id_vec);
/* Allocate a CosNaming::Name (sequence of CosNaming::NameComponent) */
CosNaming_Name *name = CosNaming_Name__alloc();
g_assert (id_vec_len (id_vec) > 0);
name->_buffer = CORBA_sequence_CosNaming_NameComponent_allocbuf(len);
name->_maximum = len;
name->_length = 0;
/* Relinquish ownership of the NameComponent to the
* sequence. When CORBA_free is called on it later, the
* NameComponent will be freed */
CORBA_sequence_set_release (name, TRUE);
/* iterate components of name and create sub-context
* (directory) if needed */
for (i = 0; i < len; ++i) {
name->_length = i+1;
name->_buffer[i].id = CORBA_string_dup(id_vec[i]);
name->_buffer[i].kind = CORBA_string_dup("");
/* don't know what 'kind' shall be good for */
}
retval = CosNaming_NamingContext_resolve (name_service,
name,
ev);
if (etk_raised_exception (ev)) {
CORBA_free (name);
return CORBA_OBJECT_NIL;
}
return retval;
}
Example 5-36. name-resolve-client.c
/*
* Name-Resolve client program.. Hacked by Frank Rehberger
* <F.Rehberger@xtradyne.de>
*
* Client connects to name-service and resolves object reference from server and
* forwards console input to name-resolve-server. A dot . as single character
* in input terminates the client.
*/
#include <stdio.h>
#include <signal.h>
#include <orbit/orbit.h>
/*
* This header file was generated from the idl
*/
#include "name-resolve.h"
#include "examples-toolkit.h" /* provides etk_abort_if_exception */
static CORBA_ORB global_orb = CORBA_OBJECT_NIL; /* global orb */
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
* function, which will terminate the processes main loop.
*/
static
void
client_shutdown (int sig)
{
CORBA_Environment local_ev[1];
CORBA_exception_init(local_ev);
if (global_orb != CORBA_OBJECT_NIL)
{
CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
etk_abort_if_exception (local_ev, "caught exception");
}
}
/* Inits ORB @orb using @argv arguments for configuration. For each
* ORBit options consumed from vector @argv the counter of @argc_ptr
* will be decremented. Signal handler is set to call
* echo_client_shutdown function in case of SIGINT and SIGTERM
* signals. If error occures @ev points to exception object on
* return.
*/
static
void
client_init (int *argc_ptr,
char *argv[],
CORBA_ORB *orb,
CORBA_Environment *ev)
{
/* init signal handling */
signal(SIGINT, client_shutdown);
signal(SIGTERM, client_shutdown);
/* create Object Request Broker (ORB) */
(*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-mt-orb", ev);
if (etk_raised_exception(ev)) return;
}
/* Releases @servant object and finally destroys @orb. If error
* occures @ev points to exception object on return.
*/
static
void
client_cleanup (CORBA_ORB orb,
CORBA_Object service,
CORBA_Environment *ev)
{
/* releasing managed object */
CORBA_Object_release(service, ev);
if (etk_raised_exception(ev)) return;
/* tear down the ORB */
if (orb != CORBA_OBJECT_NIL)
{
/* going to destroy orb.. */
CORBA_ORB_destroy(orb, ev);
if (etk_raised_exception(ev)) return;
}
}
/**
*
*/
static
void
client_run (Examples_NameResolve_Service service,
CORBA_Environment *ev)
{
char filebuffer[1024+1];
g_print("Type any text to console to be sent to server,\n"
"a single dot in line will terminate input\n");
while( fgets(filebuffer,1024,stdin) ) {
if( filebuffer[0] == '.' && filebuffer[1] == '\n' )
break;
/* chop the newline off */
filebuffer[strlen(filebuffer)-1] = '\0';
/* using the echoString method in the Echo object
* this is defined in the echo.h header, compiled from
* echo.idl */
Examples_NameResolve_Service_echoString (service,
filebuffer,
ev);
if (etk_raised_exception (ev)) return;
}
}
/*
* main
*/
int
main(int argc, char* argv[])
{
Examples_NameResolve_Service service = CORBA_OBJECT_NIL;
CosNaming_NamingContext name_service = CORBA_OBJECT_NIL;
gchar *id[] = {"Examples", "NameResolve", "Service", NULL};
CORBA_Environment ev[1];
CORBA_exception_init(ev);
client_init (&argc, argv, &global_orb, ev);
etk_abort_if_exception(ev, "init failed");
g_print ("Resolving service reference from name-service with id \"%s/%s/%s\"\n", id[0], id[1], id[2]);
name_service = etk_get_name_service (global_orb, ev);
etk_abort_if_exception(ev, "failed resolving name-service");
service
= (Examples_NameResolve_Service)
etk_name_service_resolve (name_service, id, ev);
etk_abort_if_exception(ev, "failed resolving service at name-service");
client_run (service, ev);
etk_abort_if_exception(ev, "service not reachable");
client_cleanup (global_orb, service, ev);
etk_abort_if_exception(ev, "cleanup failed");
exit (0);
}
Example 5-37. name-resolve-server.c
/*
* echo-server program. Hacked from Echo test suite by
* <birney@sanger.ac.uk>, ORBit2 udpate by Frank Rehberger
* <F.Rehberger@xtradyne.de>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <orbit/orbit.h>
#include "name-resolve-skelimpl.c"
#include "examples-toolkit.h" /* provides etk_abort_if_exception */
static CORBA_ORB global_orb = CORBA_OBJECT_NIL; /* global orb */
static PortableServer_POA root_poa = CORBA_OBJECT_NIL; /* root POA
/* Is called in case of process signals. it invokes CORBA_ORB_shutdown()
* function, which will terminate the processes main loop.
*/
static
void
server_shutdown (int sig)
{
CORBA_Environment local_ev[1];
CORBA_exception_init(local_ev);
if (global_orb != CORBA_OBJECT_NIL)
{
CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
etk_abort_if_exception (local_ev, "caught exception");
}
}
/* Inits ORB @orb using @argv arguments for configuration. For each
* ORBit options consumed from vector @argv the counter of @argc_ptr
* will be decremented. Signal handler is set to call
* echo_server_shutdown function in case of SIGINT and SIGTERM
* signals. If error occures @ev points to exception object on
* return.
*/static
void
server_init (int *argc_ptr,
char *argv[],
CORBA_ORB *orb,
PortableServer_POA *poa,
CORBA_Environment *ev)
{
PortableServer_POAManager poa_manager = CORBA_OBJECT_NIL;
CORBA_Environment local_ev[1];
CORBA_exception_init(local_ev);
/* init signal handling */
signal(SIGINT, server_shutdown);
signal(SIGTERM, server_shutdown);
/* create Object Request Broker (ORB) */
(*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-mt-orb", ev);
if (etk_raised_exception(ev))
goto failed_orb;
(*poa) = (PortableServer_POA)
CORBA_ORB_resolve_initial_references(*orb, "RootPOA", ev);
if (etk_raised_exception(ev))
goto failed_poa;
poa_manager = PortableServer_POA__get_the_POAManager(*poa, ev);
if (etk_raised_exception(ev))
goto failed_poamanager;
PortableServer_POAManager_activate(poa_manager, ev);
if (etk_raised_exception(ev))
goto failed_activation;
CORBA_Object_release ((CORBA_Object) poa_manager, ev);
return;
failed_activation:
failed_poamanager:
CORBA_Object_release ((CORBA_Object) poa_manager, local_ev);
failed_poa:
CORBA_ORB_destroy(*orb, local_ev);
failed_orb:
return;
}
/* Entering main loop @orb handles incoming request and delegates to
* servants. If error occures @ev points to exception object on
* return.
*/
static void
server_run (CORBA_ORB orb,
CORBA_Environment *ev)
{
/* enter main loop until SIGINT or SIGTERM */
CORBA_ORB_run(orb, ev);
if (etk_raised_exception(ev)) return;
/* user pressed SIGINT or SIGTERM and in signal handler
* CORBA_ORB_shutdown(.) has been called */
}
/* Releases @servant object and finally destroys @orb. If error
* occures @ev points to exception object on return.
*/
static void
server_cleanup (CORBA_ORB orb,
PortableServer_POA poa,
CORBA_Object ref,
CORBA_Environment *ev)
{
PortableServer_ObjectId *objid = NULL;
objid = PortableServer_POA_reference_to_id (poa, ref, ev);
if (etk_raised_exception(ev)) return;
/* Servant: deactivatoin - will invoke __fini destructor */
PortableServer_POA_deactivate_object (poa, objid, ev);
if (etk_raised_exception(ev)) return;
PortableServer_POA_destroy (poa, TRUE, FALSE, ev);
if (etk_raised_exception(ev)) return;
CORBA_free (objid);
CORBA_Object_release ((CORBA_Object) poa, ev);
if (etk_raised_exception(ev)) return;
CORBA_Object_release (ref, ev);
if (etk_raised_exception(ev)) return;
/* ORB: tear down the ORB */
if (orb != CORBA_OBJECT_NIL)
{
/* going to destroy orb.. */
CORBA_ORB_destroy(orb, ev);
if (etk_raised_exception(ev)) return;
}
}
/* Creates servant and registers in context of ORB @orb. The ORB will
* delegate incoming requests to specific servant object. @return
* object reference. If error occures @ev points to exception object
* on return.
*/
static CORBA_Object
server_activate_service (CORBA_ORB orb,
PortableServer_POA poa,
CORBA_Environment *ev)
{
Examples_NameResolve_Service ref = CORBA_OBJECT_NIL;
ref = impl_Examples_NameResolve_Service__create (poa, ev);
if (etk_raised_exception(ev))
return CORBA_OBJECT_NIL;
return ref;
}
/*
* main
*/
int
main (int argc, char *argv[])
{
CORBA_Object servant = CORBA_OBJECT_NIL;
CosNaming_NamingContext name_service = CORBA_OBJECT_NIL;
gchar *id[] = {"Examples", "NameResolve", "Service", NULL};
CORBA_Environment ev[1];
CORBA_exception_init(ev);
server_init (&argc, argv, &global_orb, &root_poa, ev);
etk_abort_if_exception(ev, "failed ORB init");
servant = server_activate_service (global_orb, root_poa, ev);
etk_abort_if_exception(ev, "failed activating service");
g_print ("Binding service reference at name service against id: %s/%s/%s\n\n", id[0], id[1], id[2]);
name_service = etk_get_name_service (global_orb, ev);
etk_abort_if_exception(ev, "failed resolving name-service");
etk_name_service_bind (name_service, servant, id, ev);
etk_abort_if_exception(ev, "failed binding of service");
server_run (global_orb, ev);
etk_abort_if_exception(ev, "failed entering main loop");
server_cleanup (global_orb, root_poa, servant, ev);
etk_abort_if_exception(ev, "failed cleanup");
exit (0);
}
Example 5-38. name-resolve-skelimpl.c
/* This is a template file generated by command */
/* orbit-idl-2 --skeleton-impl name-resolve.idl */
/* User must edit this file, inserting servant */
/* specific code between markers. */
#include "name-resolve.h"
/*** App-specific servant structures ***/
typedef struct
{
POA_Examples_NameResolve_Service servant;
PortableServer_POA poa;
/* ------ add private attributes here ------ */
/* ------ ---------- end ------------ ------ */
} impl_POA_Examples_NameResolve_Service;
/*** Implementation stub prototypes ***/
static void
impl_Examples_NameResolve_Service__fini(impl_POA_Examples_NameResolve_Service
* servant, CORBA_Environment * ev);
static void
impl_Examples_NameResolve_Service_echoString
(impl_POA_Examples_NameResolve_Service * servant, const CORBA_char * input,
CORBA_Environment * ev);
/*** epv structures ***/
static PortableServer_ServantBase__epv
impl_Examples_NameResolve_Service_base_epv = {
NULL, /* _private data */
(gpointer) & impl_Examples_NameResolve_Service__fini, /* finalize routine */
NULL, /* default_POA routine */
};
static POA_Examples_NameResolve_Service__epv
impl_Examples_NameResolve_Service_epv = {
NULL, /* _private */
(gpointer) & impl_Examples_NameResolve_Service_echoString,
};
/*** vepv structures ***/
static POA_Examples_NameResolve_Service__vepv
impl_Examples_NameResolve_Service_vepv = {
&impl_Examples_NameResolve_Service_base_epv,
&impl_Examples_NameResolve_Service_epv,
};
/*** Stub implementations ***/
static Examples_NameResolve_Service
impl_Examples_NameResolve_Service__create(PortableServer_POA poa,
CORBA_Environment * ev)
{
Examples_NameResolve_Service retval;
impl_POA_Examples_NameResolve_Service *newservant;
PortableServer_ObjectId *objid;
newservant = g_new0(impl_POA_Examples_NameResolve_Service, 1);
newservant->servant.vepv = &impl_Examples_NameResolve_Service_vepv;
newservant->poa =
(PortableServer_POA) CORBA_Object_duplicate((CORBA_Object) poa, ev);
POA_Examples_NameResolve_Service__init((PortableServer_Servant) newservant,
ev);
/* Before servant is going to be activated all
* private attributes must be initialized. */
/* ------ init private attributes here ------ */
/* ------ ---------- end ------------- ------ */
objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);
return retval;
}
/**
* impl_Examples_NameResolve_Service__fini
*
* Destructor called after servant has been deactivated finally.
* In case any active operation invocation, method call is being delayed.
* Note, in former versions of ORBit2 this function would have been
* named impl_Examples_NameResolve_Service__destroy.
**/
static void
impl_Examples_NameResolve_Service__fini(impl_POA_Examples_NameResolve_Service
* servant, CORBA_Environment * ev)
{
CORBA_Object_release((CORBA_Object) servant->poa, ev);
/* No further remote method calls are delegated to
* servant and you may free your private attributes. */
/* ------ free private attributes here ------ */
/* ------ ---------- end ------------- ------ */
POA_Examples_NameResolve_Service__fini((PortableServer_Servant) servant,
ev);
g_free(servant);
}
static void
impl_Examples_NameResolve_Service_echoString
(impl_POA_Examples_NameResolve_Service * servant, const CORBA_char * input,
CORBA_Environment * ev)
{
/* ------ insert method code here ------ */
g_print (">> %s\n", input);
/* ------ ---------- end ------------ ------ */
}
Example 5-39. Makefile
PREFIX ?= /usr
CC = gcc
TARGETS=name-resolve-client name-resolve-server
ORBIT_IDL=$(PREFIX)/bin/orbit-idl-2
CFLAGS=-DORBIT2=1 -D_REENTRANT -I$(PREFIX)/include/orbit-2.0 \
-I$(PREFIX)/include/linc-1.0 -I$(PREFIX)/include/glib-2.0 \
-I$(PREFIX)/lib/glib-2.0/include -g
LDFLAGS= -Wl,--export-dynamic -L$(PREFIX)/lib -lORBit-2 -llinc -lgmodule-2.0 \
-ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \
-lORBitCosNaming-2
IDLOUT=name-resolve-common.c name-resolve-stubs.c name-resolve-skels.c name-resolve.h
all: $(IDLOUT) name-resolve-client name-resolve-server
name-resolve-server.o: name-resolve-server.c name-resolve-skelimpl.c
name-resolve-client : name-resolve-client.o name-resolve-stubs.o name-resolve-common.o examples-toolkit.o
name-resolve-server : name-resolve-server.o name-resolve-skels.o name-resolve-common.o examples-toolkit.o name-resolve-skelimpl.o
$(IDLOUT): name-resolve.idl
$(ORBIT_IDL) name-resolve.idl
%-skelimpl.c: %.idl
$(ORBIT_IDL) --skeleton-impl $^
clean:
rm -rf *.o *~ $(IDLOUT) *.ior *.ref
distclean: clean
rm -rf name-resolve-client name-resolve-server