diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/ic/examples/c-server | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/ic/examples/c-server')
-rw-r--r-- | lib/ic/examples/c-server/Makefile | 89 | ||||
-rw-r--r-- | lib/ic/examples/c-server/ReadMe | 45 | ||||
-rw-r--r-- | lib/ic/examples/c-server/callbacks.c | 45 | ||||
-rw-r--r-- | lib/ic/examples/c-server/client.c | 124 | ||||
-rw-r--r-- | lib/ic/examples/c-server/client.erl | 44 | ||||
-rw-r--r-- | lib/ic/examples/c-server/random.idl | 49 | ||||
-rw-r--r-- | lib/ic/examples/c-server/server.c | 245 |
7 files changed, 641 insertions, 0 deletions
diff --git a/lib/ic/examples/c-server/Makefile b/lib/ic/examples/c-server/Makefile new file mode 100644 index 0000000000..caf4306932 --- /dev/null +++ b/lib/ic/examples/c-server/Makefile @@ -0,0 +1,89 @@ +# +# %CopyrightBegin% +# +# Copyright Ericsson AB 1998-2009. All Rights Reserved. +# +# The contents of this file are subject to the Erlang Public License, +# Version 1.1, (the "License"); you may not use this file except in +# compliance with the License. You should have received a copy of the +# Erlang Public License along with this software. If not, it can be +# retrieved online at http://www.erlang.org/. +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +# the License for the specific language governing rights and limitations +# under the License. +# +# %CopyrightEnd% +# +# +# Point this at your version of OTP +OTPROOT=/usr/local/otp/daily_build/otp_beam_sunos5_r8a.latest + +# Type actual IC Version +ICVSN=4.1.1 + +# Type actual Erl Interface Vesrion +EIVSN=3.3.0 + +# IDL file(s) +IDLS=random.idl + +# Own C-server files +CSRV=server callbacks + +# Own C-client files +CCL=client + +# Generated C-server files +GCSRVS=rmod_random__s + +# Generated C-server files +GCCLS=rmod_random + +# Includes +IFLAGS=-I$(OTPROOT)/lib/ic-$(ICVSN)/include \ + -I$(OTPROOT)/lib/erl_interface-$(EIVSN)/include + +LDFLAGS=-L$(OTPROOT)/lib/ic-$(ICVSN)/priv/lib \ + -L$(OTPROOT)/lib/erl_interface-$(EIVSN)/lib + +LDLIBS=-lic -lerl_interface -lei -lnsl -lsocket + + +# Erlang compiler +ERLC=$(OTPROOT)/bin/erlc + +# Erlang compiler flags. +EFLAGS='+{preproc_flags,"-I $(OTPROOT)/usr/include"}' '+{scoped_op_calls,true}' + + +# C compiler +CC=gcc + +# C compiler flags +CFLAGS=-ggdb -O2 -Wall $(IFLAGS) + + +all: server client erlclient + + +server: + $(ERLC) $(EFLAGS) '+{be,c_server}' $(IDLS) + $(CC) $(IFLAGS) -c $(CSRV:=.c) $(GCSRVS:=.c) + $(CC) $(CSRV:=.o) $(GCSRVS:=.o) -o $@ $(LDFLAGS) $(LDLIBS) + +client: + $(ERLC) $(EFLAGS) '+{be,c_client}' $(IDLS) + $(CC) $(IFLAGS) -c $(CCL:=.c) $(GCCLS:=.c) + $(CC) $(CCL:=.o) $(GCCLS:=.o) -o $@ $(LDFLAGS) $(LDLIBS) + +erlclient: + $(ERLC) $(EFLAGS) '+{be,erl_genserv}' $(IDLS) + $(ERLC) *.erl + + +clean: + /bin/rm -f $(GCCLS:=.o) $(GCCLS:=.c) $(GCSRVS:=.o) $(GCSRVS:=.c) $(CCL:=.o) $(CSRV:=.o) *.jam *.beam oe* *.h *.hrl *~ core server client + + diff --git a/lib/ic/examples/c-server/ReadMe b/lib/ic/examples/c-server/ReadMe new file mode 100644 index 0000000000..69fce4cd07 --- /dev/null +++ b/lib/ic/examples/c-server/ReadMe @@ -0,0 +1,45 @@ +This is a short description on the use of the client demo, +a client that initiates and uses a random number generator +that lies on a C-server. + +Instructions. + +1) Modify the OTPROOT variable on the Makefile to point + to the root for your erlang instalation. + Modify IC and Erl_Interface versions to agree your + OTP version. + +2) + Type : + ------ + + make ( generates and compiles all code ) + + server ( starts the c-server ) + + + To test the c-client against the c-server start a new terminal window and type : + -------------------------------------------------------------------------------- + + client ( calls the server ) + + + To test the erlang-client against the c-server start a new terminal window and type : + ------------------------------------------------------------------------------------- + + + erl -sname client -setcookie flash ( start erlang ) + + client:init(1,2,3). ( initiates the random generator ) + + client:produce(). ( calls the random generator ) + + + + + + + + + + diff --git a/lib/ic/examples/c-server/callbacks.c b/lib/ic/examples/c-server/callbacks.c new file mode 100644 index 0000000000..d50d26ced1 --- /dev/null +++ b/lib/ic/examples/c-server/callbacks.c @@ -0,0 +1,45 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ + +#include <stdlib.h> +#include "rmod_random__s.h" + + +rmod_random_produce__rs* +rmod_random_produce__cb(rmod_random oe_obj, double *rs, CORBA_Environment *oe_env) + +{ + *rs = (double) rand(); + + return (rmod_random_produce__rs*) NULL; +} + + +rmod_random_init__rs* +rmod_random_init__cb(rmod_random oe_obj, long* seed1, long* seed2, long* seed3, CORBA_Environment *oe_env) + +{ + srand(*seed1 * *seed2 * *seed3); + + return (rmod_random_init__rs*) NULL; +} + + + diff --git a/lib/ic/examples/c-server/client.c b/lib/ic/examples/c-server/client.c new file mode 100644 index 0000000000..fa570089b5 --- /dev/null +++ b/lib/ic/examples/c-server/client.c @@ -0,0 +1,124 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ + +/* Include the interface function, and ei_connect */ +#include "rmod_random.h" +#include "ei_connect.h" + +/* Assign your own node name here */ +#define SNODE "babbis@balin" +#define SERVER "rmod_random_impl" +#define COOKIE "flash" +#define CLNODE "c47@balin" +#define INBUFSZ 1024 +#define OUTBUFSZ 1024 + +/* Stopping node */ +void client_exit(CORBA_Environment *env) { + + /* Free env & buffers */ + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + + close(env->_fd); + exit(1); +} + +int main() +{ + double result=0; + int i=0; + erlang_pid pid; + CORBA_Environment *env; + ei_cnode ec; + + /* Create and init CORBA_Environment */ + env = CORBA_Environment_alloc(INBUFSZ,OUTBUFSZ); + + /* Initiating the connection */ + ei_connect_init(&ec, "c47", COOKIE, 0); + + /* Initiating pid*/ + strcpy(pid.node, CLNODE); + pid.num = 99; + pid.serial = 0; + pid.creation = 0; + + /* Fixing environment variable */ + env->_fd = ei_connect(&ec, SNODE); + strcpy(env->_regname,SERVER); + env->_to_pid = NULL; + env->_from_pid = &pid; + + if (env->_fd < 0) { + fprintf(stderr,"Error : Cannot connect to Server\n"); + + /* Free env & buffers */ + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + exit(1); + } + + /* Calling the init function */ + rmod_random_init(NULL, 1, 2, 3, env); + + switch(env->_major) { + case CORBA_NO_EXCEPTION: /* Success */ + printf("Init complete !\n"); + break; + case CORBA_SYSTEM_EXCEPTION: /* System exception */ + printf("Init call failure, reason : %s\n",(char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + client_exit(env); + default: /* Should not come here */ + client_exit(env); + } + + /* Calling the produce function */ + for(i=1; i<=10; i++) { + result = rmod_random_produce(NULL, env); + + switch(env->_major) { + case CORBA_NO_EXCEPTION: /* Success */ + break; + case CORBA_SYSTEM_EXCEPTION: /* System exception */ + printf("Init call failure, reason : %s\n",(char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + client_exit(env); + default: /* Should not come here */ + client_exit(env); + } + + printf("the random number nr%d is %f\n",i,result); + } + + /* Closing the connection */ + close(env->_fd); + + /* Free env & buffers */ + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); + + return 0; +} + diff --git a/lib/ic/examples/c-server/client.erl b/lib/ic/examples/c-server/client.erl new file mode 100644 index 0000000000..e225fc5789 --- /dev/null +++ b/lib/ic/examples/c-server/client.erl @@ -0,0 +1,44 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1998-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%%---------------------------------------------------------------------- +%%% File : client.erl +%%% Author : Babbis Xagorarakis <babbis@balin> +%%% Purpose : +%%% Created : 22 Oct 1998 by Babbis Xagorarakis <babbis@balin> +%%%---------------------------------------------------------------------- + +-module(client). +-author('babbis@balin'). + +-export([produce/0,init/3]). + +-define(SERVER,{rmod_random_impl,'babbis@balin'}). +-define(CLIENTMOD,'rmod_random'). + +produce() -> + ?CLIENTMOD:produce(?SERVER). + + +init(Seed1, Seed2, Seed3) -> + ?CLIENTMOD:init(?SERVER, Seed1, Seed2, Seed3). + + + + diff --git a/lib/ic/examples/c-server/random.idl b/lib/ic/examples/c-server/random.idl new file mode 100644 index 0000000000..b2c21bdbfd --- /dev/null +++ b/lib/ic/examples/c-server/random.idl @@ -0,0 +1,49 @@ +// ``The contents of this file are subject to the Erlang Public License, +// Version 1.1, (the "License"); you may not use this file except in +// compliance with the License. You should have received a copy of the +// Erlang Public License along with this software. If not, it can be +// retrieved via the world wide web at http://www.erlang.org/. +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +// the License for the specific language governing rights and limitations +// under the License. +// +// The Initial Developer of the Original Code is Ericsson Utvecklings AB. +// Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings +// AB. All Rights Reserved.'' +// +// $Id$ +// + +#ifndef _RANDOM_IDL +#define _RANDOM_IDL + +module rmod { + + interface random { + + double produce(); + + oneway void init(in long seed1, in long seed2, in long seed3); + + }; + +}; + +#endif + + + + + + + + + + + + + + + diff --git a/lib/ic/examples/c-server/server.c b/lib/ic/examples/c-server/server.c new file mode 100644 index 0000000000..7e3c620040 --- /dev/null +++ b/lib/ic/examples/c-server/server.c @@ -0,0 +1,245 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 1998-2009. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#ifdef __WIN32__ +#include <winsock2.h> +#include <direct.h> +#include <windows.h> +#include <winbase.h> +#else /* not __WIN32__ */ +#include <errno.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif +#include "rmod_random__s.h" +#include "ei_connect.h" + +/* Used functions */ +extern int gethostname(char *buf, int buflen); +static int getport(int sockd); +static int getlisten(int port); +static int init(ei_cnode *ec, int *sd, int *portnr, int *epmd_fd); +void terminate(int *fd, int *sd, int *epmd_fd); +static void server_loop(ei_cnode *ec, int fd, int sd); + +/* change these, or even better, make command-line args to program... */ +#define COOKIE "flash" +#define SERVER "babbis" +#define NODENAMESZ 512 +#define HOSTNAMESZ 256 +#define INBUFSZ 1024 +#define OUTBUFSZ 1024 + + +int main(int argc, char **argv) +{ + int sd; + int portnr; + int epmd_fd; + ei_cnode ec; + + /* crate file descriptors */ + if (init(&ec, &sd, &portnr, &epmd_fd) < 0) + return -1; + + /* start server loop */ + server_loop(&ec, sd, epmd_fd); + + return 0; +} + + + +static void server_loop(ei_cnode *ec, int sd, int epmd_fd) +{ + ErlConnect conn; + erlang_msg msg; + int status=1; + CORBA_Environment *env; + + /* Create and init CORBA_Environment */ + env = CORBA_Environment_alloc(INBUFSZ,OUTBUFSZ); + + while (status >= 0) { + status = 1; + + if ((env->_fd = ei_accept(ec, sd, &conn)) < 0) { + /* error */ + fprintf(stderr,"Accept failed: %s\n",strerror(errno)); + } else { + /* connection */ + fprintf(stderr,"Accepted connection from %s\n",conn.nodename); + + while (status >= 0) { + + /* write message to buffer */ + status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, &msg, &env->_iin); + switch(status) { + case ERL_SEND: + case ERL_REG_SEND : + /* do transaction with fd */ + rmod_random__switch(NULL,env); + + switch(env->_major) { + case CORBA_NO_EXCEPTION: /* Success */ + break; + case CORBA_SYSTEM_EXCEPTION: /* System exception */ + printf("Request failure, reason : %s\n",(char *) CORBA_exception_value(env)); + CORBA_exception_free(env); + break; + default: /* Should not come here */ + CORBA_exception_free(env); + break; + } + + /* send outdata */ + if (env->_iout > 0) + ei_send_encoded(env->_fd,&env->_caller,env->_outbuf,env->_iout); + break; + + case ERL_TICK : + break; + default : /* < 0 */ + printf("Connection terminated\n"); + break; + } + } + } + status=0; /* restart */ + } + + /* close file descriptors */ + terminate(&env->_fd, &sd, &epmd_fd); + + /* Free env & buffers */ + CORBA_free(env->_inbuf); + CORBA_free(env->_outbuf); + CORBA_free(env); +} + + + +static int init(int *sd, int *portnr, int *epmd_fd) +{ + char host[HOSTNAMESZ]; + char servernode[NODENAMESZ]; + struct hostent *h; + + /* get the host name */ + if ((gethostname(host,HOSTNAMESZ))) + fprintf(stderr,"can't find own hostname\n"); + else { + /* identify host */ + if (!(h = erl_gethostbyname(host))) + fprintf(stdout,"can't find own ip address\n"); + else { + + /* get a listen port. 0 means let system choose port number */ + *sd = getlisten(0); + + /* what port did we get? */ + /* this call not necessary if we specified port in call to getlisten() */ + *portnr = getport(*sd); + + /* make the nodename server@host */ + sprintf(servernode,"%s@%s",SERVER,host); + + /* initiate */ + /* cnode, host, alive, alive@host, addr, cookie, creation */ + if (ei_connect_xinit(ec, host, SERVER, servernode, + (Erl_IpAddr)(h->h_addr_list[0]), + COOKIE, 0) == 0) { + /* let epmd know we are here */ + *epmd_fd = ei_publish(ec, *portnr); + if (*epmd_fd >= 0) + return 0; + } + } + } + return -1; +} + + +void terminate(int *fd, int *sd, int *epmd_fd) { + + close(*fd); + + /* remove info from epnd */ + close(*epmd_fd); + + /* return socket */ + close(*sd); + +} + + + +/* tells you what port you are using on given socket */ +static int getport(int sockd) +{ + struct sockaddr_in addr; + int namelen = sizeof(addr); + int i; + + memset(&addr,0,sizeof(addr)); + + if ((i = getsockname(sockd,(struct sockaddr *)&addr,&namelen))<0) + return i; + + return ntohs(addr.sin_port); +} + + + +/* return a listen socket, bound to given port */ +/* specify port = 0 to let system assign port */ +static int getlisten(int port) +{ + int sockd; + struct sockaddr_in inaddr; + int opt = 1; + int i; + + /* get listen socket */ + if ((sockd = socket(AF_INET,SOCK_STREAM,0)) < 0) return sockd; + + if ((i=setsockopt(sockd,SOL_SOCKET,SO_REUSEADDR,(void *)&opt,sizeof(opt)))<0) + return i; + + /* bind to requested port */ + memset(&inaddr,0,sizeof(inaddr)); + inaddr.sin_family = AF_INET; + inaddr.sin_addr.s_addr = htonl(INADDR_ANY); + inaddr.sin_port = htons(port); + + if ((i = bind(sockd,(struct sockaddr*) &inaddr, sizeof(inaddr))) < 0) + return i; + + listen(sockd,5); + + return sockd; +} |