From 242f062386ce787b4637b945c8a764f217aab907 Mon Sep 17 00:00:00 2001 From: David Daniel Date: Fri, 20 Aug 2004 01:01:09 +0000 Subject: [PATCH] Since I'm vanishing for a few weeks, a smattering of code from FTMPI for possible consideration... This commit was SVN r2245. --- src/mca/service/stdio/Makefile | 16 + src/mca/service/stdio/README | 96 + src/mca/service/stdio/cioapp.c | 55 + src/mca/service/stdio/libcio.c | 296 +++ src/mca/service/stdio/libcio.h | 68 + src/mca/service/stdio/libsio.c | 289 +++ src/mca/service/stdio/libsio.h | 74 + src/mca/service/stdio/sioapp.c | 81 + src/mca/service/stdio/snipe_lite/debug.h | 58 + src/mca/service/stdio/snipe_lite/memory.c | 198 ++ src/mca/service/stdio/snipe_lite/msg.c | 258 +++ src/mca/service/stdio/snipe_lite/msg.h | 49 + src/mca/service/stdio/snipe_lite/msgbuf.h | 155 ++ src/mca/service/stdio/snipe_lite/msgbuf2.c | 1762 +++++++++++++++++ src/mca/service/stdio/snipe_lite/snipe_lite.c | 1007 ++++++++++ src/mca/service/stdio/snipe_lite/snipe_lite.h | 110 + src/mca/service/stdio/snipe_lite/syslog.c | 196 ++ src/mca/service/stdio/snipe_lite/syslog.h | 118 ++ 18 files changed, 4886 insertions(+) create mode 100644 src/mca/service/stdio/Makefile create mode 100644 src/mca/service/stdio/README create mode 100644 src/mca/service/stdio/cioapp.c create mode 100644 src/mca/service/stdio/libcio.c create mode 100644 src/mca/service/stdio/libcio.h create mode 100644 src/mca/service/stdio/libsio.c create mode 100644 src/mca/service/stdio/libsio.h create mode 100644 src/mca/service/stdio/sioapp.c create mode 100644 src/mca/service/stdio/snipe_lite/debug.h create mode 100644 src/mca/service/stdio/snipe_lite/memory.c create mode 100644 src/mca/service/stdio/snipe_lite/msg.c create mode 100644 src/mca/service/stdio/snipe_lite/msg.h create mode 100644 src/mca/service/stdio/snipe_lite/msgbuf.h create mode 100644 src/mca/service/stdio/snipe_lite/msgbuf2.c create mode 100644 src/mca/service/stdio/snipe_lite/snipe_lite.c create mode 100644 src/mca/service/stdio/snipe_lite/snipe_lite.h create mode 100644 src/mca/service/stdio/snipe_lite/syslog.c create mode 100644 src/mca/service/stdio/snipe_lite/syslog.h diff --git a/src/mca/service/stdio/Makefile b/src/mca/service/stdio/Makefile new file mode 100644 index 0000000000..a0aff38c1b --- /dev/null +++ b/src/mca/service/stdio/Makefile @@ -0,0 +1,16 @@ +SNL_OBJECTS = ./snipe_lite/msg.c \ + ./snipe_lite/msgbuf2.c \ + ./snipe_lite/memory.c \ + ./snipe_lite/syslog.c \ + ./snipe_lite/snipe_lite.c + +all : sioapp cioapp + +sioapp : sioapp.c + gcc -o sioapp sioapp.c libsio.c $(SNL_OBJECTS) -I./snipe_lite + +cioapp : cioapp.c + gcc -o cioapp cioapp.c libcio.c $(SNL_OBJECTS) -I./snipe_lite + +clean : + rm -f *.o sioapp cioapp diff --git a/src/mca/service/stdio/README b/src/mca/service/stdio/README new file mode 100644 index 0000000000..e48e803e8f --- /dev/null +++ b/src/mca/service/stdio/README @@ -0,0 +1,96 @@ +This should be in a design document but.... + +Random thoughts on stdio redirection. + +- stdin redirection should be buffered (i.e. fragment-based). stdin + should go to process 0. Any need to broadcast stdin? +- stdout/stderr also buffered. Fragment headers: to indicate origin, + and to handle out of order delivery in future distributed situations. +- pipes or ptys from ompid to processes. Fairly portable pty code is + in src/util/pty.c. Goal: wrap up selection of pipes vs ptys in a + transparent fashion for easy selection at compile- or run-time (MCA + parameter-based I guess). Note ptys are typically necessary when stdin + is a tty so that interactive input is possible. +- stdin redirection: base this on LA-MPI's rts/cts fragment-based + approach. +- Consider basing ompid -> mpirun stdout/stderr redirection on FTMPI + libcio/sio ported to use oob framework (tcp component for non-blocking + operation). + + + +In this directory: + +libcio/sio are the client and server parts of the FTMPI stdout and +stderr I/O forwarding. + +snipe_lite is a close analog of our OOB + + + + + +Explanatory email from Thara: + + From: angskun@cs.utk.edu + Subject: Re: libsio, libcio + Date: August 13, 2004 13:11:14 MDT + To: ddd@lanl.gov + Cc: fagg@cs.utk.edu + +Dear David, + +Everything in snipe_lite directory is for basic connection management +in FT-MPI. The libcio/sio use the snipe_lite for communication. +You may replace it with socket or OpenMPI communication library. + +cioapp.c : client/console/ application example +sioapp.c : server/daemon application example +libcio.*, libsio.* : the library and include file + +Example: +*** client/console machine *** +[angskun@torc0 ~/ioapp]$ ./cioapp 3 +Port is 6781 +[0:stdout] Hi world, my name is foo 1/5 [bar code is 0 (pid 19409)] +Hi world, my name is foo 2/5 [bar code is 0 (pid 19409)] +Hi world, my name is foo 3/5 [bar code is 0 (pid 19409)] +Hi world, my name is foo 4/5 [bar code is 0 (pid 19409)] +Hi world, my name is foo 5/5 [bar code is 0 (pid 19409)] +[1:stdout] Hi world, my name is foo 1/5 [bar code is 1 (pid 19410)] +Hi world, my name is foo 2/5 [bar code is 1 (pid 19410)] +Hi world, my name is foo 3/5 [bar code is 1 (pid 19410)] +Hi world, my name is foo 4/5 [bar code is 1 (pid 19410)] +Hi world, my name is foo 5/5 [bar code is 1 (pid 19410)] +[2:stdout] Hi world, my name is foo 1/5 [bar code is 2 (pid 19411)] +Hi world, my name is foo 2/5 [bar code is 2 (pid 19411)] +Hi world, my name is foo 3/5 [bar code is 2 (pid 19411)] +Hi world, my name is foo 4/5 [bar code is 2 (pid 19411)] +Hi world, my name is foo 5/5 [bar code is 2 (pid 19411)] +[angskun@torc0 ~/ioapp]$ + +*** server / daemon machine *** +$./sioapp torc0 6781 3 + +Best Regards, +Thara + +----- Original Message ----- +From: "David Daniel" +To: "THara Angskun" +Cc: "Graham E Fagg" +Sent: Friday, August 13, 2004 2:09 PM +Subject: libsio, libcio + +Thara + +I'm looking at using libcio/sio as a starting point for standard I/O +redirection in Open MPI. + +Graham mentioned that you had some tests for testing them on their own. +If you could let me have a copy that would be very helpful. + +Thanks, David +-- +David Daniel +1-505-667-0883 +Advanced Computing Laboratory, LANL, MS-B287, Los Alamos NM 87545, USA diff --git a/src/mca/service/stdio/cioapp.c b/src/mca/service/stdio/cioapp.c new file mode 100644 index 0000000000..1d69170ebb --- /dev/null +++ b/src/mca/service/stdio/cioapp.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define TIMEOUT 500 +#define SERV_PORT 6780 + + +int setupContactPoint(int *port) +{ + int listenfd, rc; + struct sockaddr_in servaddr; + + listenfd = socket(AF_INET, SOCK_STREAM, 0); + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + (*port) = SERV_PORT; + servaddr.sin_port = htons((*port)); + while((rc=bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)))!=0) { + servaddr.sin_port = htons(++(*port)); + } + listen(listenfd, 5); + return listenfd; +} + +int main(int argc,char **argv) +{ + int port,listenfd; + int number_of_server_child=0; + int n_child; + int ret; + + if(argc!=2) { + printf("%s <#of server's child process>\n",argv[0]); + exit(1); + } + + listenfd=setupContactPoint(&port); + n_child=atoi(argv[1]); + printf("Port is %d\n",port); + + rioc_init(listenfd, 0); + ret=rioc_poll(TIMEOUT,&number_of_server_child); + while(ret!=0 || number_of_server_child != n_child) { + ret=rioc_poll(TIMEOUT,&number_of_server_child); + } +} diff --git a/src/mca/service/stdio/libcio.c b/src/mca/service/stdio/libcio.c new file mode 100644 index 0000000000..728f3747d8 --- /dev/null +++ b/src/mca/service/stdio/libcio.c @@ -0,0 +1,296 @@ +/* + HARNESS G_HCORE + HARNESS FT_MPI + HARNESS FTMPI_NOTIFIER + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + THara Angskun + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#include "libcio.h" +#include "debug.h" + +static int rioc_pair[RIO_MAXFD]; +static int c_num_pair; +static int main_fd; + +/* rioc_init - initialize data structure +@param fd file descriptor +@block block flag (1== block,0==nonblock) +*/ +int rioc_init(int fd,int block) +{ + int i,s; + for(i=0;i=c_num_pair) break; + } +#endif + return RIO_SUCCESS; +} + +/* rioc_poll - startup I/O redirection (NOTE: This function return only no valid pair of src/dest left or timeout) +@param timeout timeout (-1 for infinity) +@return number of connection left before timeout +*/ +int rioc_poll(int timeout, int *ncon) +{ + + int i,count; + struct pollfd *poll_fd; + struct timeval begin, current; + char buf[RIO_MAXBUF]; + int max_pair; + int ret; + int s; + long diff; + int update; + int active; + +#ifndef WIN32 + gettimeofday(&begin,NULL); + poll_fd = NULL; + rioc_pollinit(&poll_fd); + update=0; + + do { + gettimeofday(¤t,NULL); + diff=(1000000*(current.tv_sec-begin.tv_sec)) + (current.tv_usec-begin.tv_usec); + diff=diff/1000; /* millisecond */ + if(timeout>=0) { + if(diff > timeout) { + if((poll_fd)!=NULL) { + _FREE(poll_fd); + } + if(c_num_pair!=0) return c_num_pair-1; + return c_num_pair; + } + } + + if((ret=poll(poll_fd, c_num_pair, timeout)) <0) { + if((poll_fd)!=NULL) { + _FREE(poll_fd); + } + return RIO_EPOLL; + } + if(ret==0) { /* time out */ + if((poll_fd)!=NULL) { + _FREE(poll_fd); + } + if(c_num_pair!=0) return c_num_pair-1; + return c_num_pair; + } + max_pair=c_num_pair; /* we need max_pair because c_num_pair is dynamic value */ + active=0; + for(i=0;i1); + +/* close(main_fd); */ + + if((poll_fd)!=NULL) { + _FREE(poll_fd); + } + + if(c_num_pair!=0) return c_num_pair-1; +#endif + return c_num_pair; +} + +/* rioc_getoutput +@param mainfd main output file descriptor to accept output +@param expected_con expected number of connection +*/ +int rioc_getoutput(int mainfd,int expected_con) +{ + fd_set rfds, rfds_bak; + int maxfd, minfd, i, ret; + int active_con; /* number of active connection */ + char buf[RIO_MAXBUF]; + int fd; + int updated=0; + int curcon=0; + int respawn=0; + +#ifndef WIN32 + FD_ZERO(&rfds_bak); + FD_SET(mainfd,&rfds_bak); + maxfd=mainfd+1; + minfd=mainfd; + updated=1; + + while(expected_con > 0) { + + if(updated>0) { + FD_ZERO(&rfds); + maxfd=0; + minfd=0; + for(fd=0;fd=maxfd) maxfd=fd+1; + if(fd 0) { + if(FD_ISSET(i,&rfds)) { + if(i==mainfd) { + ret = allowconn (i, 0, NULL); + if(ret>0) { + FD_SET(ret,&rfds_bak); + updated=1; + curcon++; + if(curcon>expected_con) { + respawn=1; + } + if(respawn==1) { + expected_con++; + } + } + } else { + ret=readmsgconn(i,buf,RIO_MAXBUF); + if(ret<=0) { + close(i); + expected_con--; + FD_CLR(i,&rfds_bak); + updated=1; + } else { + buf[ret]='\0'; + printf("%s",buf); + buf[0]='\0'; + fflush(stdout); + } + } + active_con--; + } + i++; + } + } +#endif + return RIO_SUCCESS; +} diff --git a/src/mca/service/stdio/libcio.h b/src/mca/service/stdio/libcio.h new file mode 100644 index 0000000000..962dac6cfe --- /dev/null +++ b/src/mca/service/stdio/libcio.h @@ -0,0 +1,68 @@ +/* + HARNESS G_HCORE + HARNESS FT_MPI + HARNESS FTMPI_NOTIFIER + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + THara Angskun + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#ifndef __RIO_H +#define __RIO_H + + +#include +#include +#ifndef WIN32 +#include +#include /* for FD_SETSIZE */ +#include +#include +#include +#include +#include "snipe_lite.h" + +#else +#include "../../wincomm/wincomm.h" +#endif + +#define RIO_SUCCESS 0 +#define RIO_EPOLL -1 + +#define RIO_MAXFD FD_SETSIZE +#define RIO_MAXBUF 8192 + + + +int rioc_init(int main_fd,int block); +int rioc_poll(int timeout,int *ncon); +int rioc_register_socket(int fd); +int rioc_stop (void); +#endif diff --git a/src/mca/service/stdio/libsio.c b/src/mca/service/stdio/libsio.c new file mode 100644 index 0000000000..5bb9f88b7d --- /dev/null +++ b/src/mca/service/stdio/libsio.c @@ -0,0 +1,289 @@ +/* + HARNESS G_HCORE + HARNESS FT_MPI + HARNESS FTMPI_NOTIFIER + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + THara Angskun + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#include "libsio.h" +#include "debug.h" + +static struct pair rios_pair[RIO_MAXFD]; +static int s_num_pair; +static struct pollfd* ppoll = NULL; +static int ppoll_space = 0; + +/* rios_init - initialize data structure +*/ +int rios_init(void) +{ + int i; + + for(i=0;i= RIO_MAXFD || rios_pair[src_fd].sockfd==-1 ) { + return RIO_EINVLFD; + } + close(src_fd); + if(rios_pair[src_fd].mypair==-1) { + writemsgconn(rios_pair[src_fd].sockfd,"",0); /* tell listener to close connection */ + close(rios_pair[src_fd].sockfd); + } else { + rios_pair[rios_pair[src_fd].mypair].mypair=-1; + rios_pair[src_fd].mypair=-1; + } + rios_pair[src_fd].sockfd=-1; + rios_pair[src_fd].silent=0; /* reset it to normal */ + if(rios_pair[src_fd].name!=NULL) _FREE(rios_pair[src_fd].name); + rios_pair[src_fd].name=NULL; + s_num_pair--; + return RIO_SUCCESS; +} + +/* rios_register_dup +@param template_fd +@param my_fd +@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up) +*/ +int rios_register_dup(char *name,int template_fd,int my_fd, int silent) +{ + if(template_fd <0 || template_fd >= RIO_MAXFD || rios_pair[template_fd].sockfd == -1 || my_fd < 0 || my_fd >= RIO_MAXFD) { + return RIO_EINVLFD; + } + rios_pair[my_fd].sockfd=rios_pair[template_fd].sockfd; + rios_pair[my_fd].mypair=template_fd; + rios_pair[template_fd].mypair=my_fd; + if(name!=NULL) { + rios_pair[my_fd].name=_MALLOC(sizeof(char)*(strlen(name)+1)); + strcpy(rios_pair[my_fd].name,name); + } + rios_pair[my_fd].silent=silent; + s_num_pair++; + return RIO_SUCCESS; +} + +/* rios_register_pipe2_socket - Register I/O +@param src_fd source file descriptor +@param dest_fd destination file descriptor +@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up) +*/ +int rios_register_pipe2_socket(char *name,int src_fd,int dest_fd, int silent) +{ + if(src_fd <0 || src_fd >= RIO_MAXFD || dest_fd < 0 || dest_fd >= RIO_MAXFD) { + return RIO_EINVLFD; + } + rios_pair[src_fd].sockfd=dest_fd; + if(name!=NULL) { + rios_pair[src_fd].name=_MALLOC(sizeof(char)*(strlen(name)+1)); + strcpy(rios_pair[src_fd].name,name); + } + rios_pair[src_fd].silent=silent; + s_num_pair++; + return RIO_SUCCESS; +} + +/* rios_register_pipe2_host_port - Register I/O +@param src_fd source file descriptor +@param host hostname +@param port port +@param slient slient flags (-1 is yell, 0 is normal, 1 is shut up) +*/ +int rios_register_pipe2_host_port(char *name,int src_fd,char *host,int port, int silent) +{ + int dest_fd; + dest_fd = getconn (host, &port, 10); /* search a range of 10 */ + if(dest_fd<0) { + return RIO_EINVLFD; + } + return rios_register_pipe2_socket(name,src_fd,dest_fd,silent); +} + +/* rios_register_pipe2_addr_port - Register I/O +@param src_fd source file descriptor +@param addr address +@param port port +*/ +int rios_register_pipe2_addr_port(char *name,int src_fd,long addr,int port, int silent) +{ + int dest_fd; + dest_fd = getconn_addr (addr, &port, 10); /* search a range of 10 */ + if(dest_fd<0) { + return RIO_EINVLFD; + } + return rios_register_pipe2_socket(name,src_fd,dest_fd,silent); +} + +/* rios_pollinit - init poll call every time if number of pair has been changed +@param poll_fd poll file descriptor list. +@param free_me free pollfd +*/ +int rios_pollinit(struct pollfd **poll_fd,int free_me) +{ + int i,j; + + *poll_fd = NULL; + if(s_num_pair <= 0 ) return RIO_EINVLPAIR; + + if( ppoll_space < s_num_pair ) { + if( ppoll != NULL ) _FREE( ppoll ); + ppoll_space = s_num_pair + (s_num_pair >> 1); + ppoll = (struct pollfd*)_MALLOC( sizeof(struct pollfd) * ppoll_space ); + } + j=0; + for(i=0;i=s_num_pair) break; + } + *poll_fd = ppoll; + return RIO_SUCCESS; +} + +/* rios_poll - startup I/O redirection (NOTE: This function return only no valid pair of src/dest left or timeout) +@param timeout timeout (-1 for infinity) +@return number of connection left before timeout +*/ +int rios_poll(int timeout) +{ + + int i,count; + struct pollfd *poll_fd; + struct timeval begin, current; + char buf[RIO_MAXBUF]; + char tmpbuf[RIO_MAXBUF+500]; + int max_pair; + int ret; + long diff; + + gettimeofday(&begin,NULL); + poll_fd = NULL; + ret=rios_pollinit(&poll_fd,0); + if(ret<0) { + return ret; + } + + while(s_num_pair>0) { + gettimeofday(¤t,NULL); + diff=(1000000*(current.tv_sec-begin.tv_sec)) + (current.tv_usec-begin.tv_usec); + diff=diff/1000; /* millisecond */ + if(diff > timeout) { + return s_num_pair; + } + + if((ret=poll(poll_fd, s_num_pair, timeout)) <0) { + return RIO_EPOLL; + } + if(ret==0) { /* time out */ + return s_num_pair; + } + max_pair=s_num_pair; /* we need max_pair because s_num_pair is dynamic value */ + for(i=0;i + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#ifndef __RIO_H +#define __RIO_H + + +#include +#include +#include +#include /* for FD_SETSIZE */ +#include +#include +#include +#include +#include "snipe_lite.h" + +#define RIO_SUCCESS 0 +#define RIO_EPOLL -1 +#define RIO_EINVLFD -2 +#define RIO_EINVLPAIR -3 + +#define RIO_MAXFD FD_SETSIZE +#define RIO_MAXBUF 8192 + +struct pair { + char *name; + int sockfd; + int mypair; + int silent; /* -1 = yell, 0 = normal, 1= shut up. */ +}; + +int rios_init(void); +int rios_poll(int timeout); +int rios_register_pipe2_socket(char *name,int srcfd,int destfd,int silent); +int rios_register_pipe2_host_port(char *name,int srcfd, char* host, int port, int silent); +int rios_register_pipe2_addr_port(char *name,int srcfd, long addr, int port, int silent); +int rios_register_dup(char *name,int template_fd,int my_fd, int silent); +int rios_unregister(int srcfd); +int rios_stop (void); +#endif diff --git a/src/mca/service/stdio/sioapp.c b/src/mca/service/stdio/sioapp.c new file mode 100644 index 0000000000..8fe3a55d18 --- /dev/null +++ b/src/mca/service/stdio/sioapp.c @@ -0,0 +1,81 @@ +#include +#include "libsio.h" + +#define TIMEOUT 500 + +/* +This file is an example for application that use libsio +It simply create numbers of processes and sent their output to +speicify host and port +*/ + +struct rio { + int pid; + int pp[2]; /* stdout */ + int pp2[2]; /* stderr */ +} *rios; + +int main(int argc,char **argv) +{ + + int nchild, ret; + int entry=0; + char cioapp_host[256]; + char buf[256]; + int cioapp_port; + int startup_silent=0; /* 1=silent, 0= verbose */ + int pid,k; + + if(argc!=4) { + printf("%s <#of child processes>\n",argv[0]); + exit(1); + } + + strcpy(cioapp_host,argv[1]); + cioapp_port=atoi(argv[2]); + nchild=atoi(argv[3]); + if(nchild <1) { + printf("#of child must be more than 1\n"); + exit(1); + } + + rios_init(); + rios=(struct rio *)malloc(sizeof(struct rio)*nchild); + + for(entry=0;entry + +/* AIX requires this to be the first thing in the file. */ +#ifdef HAVE_ALLOCA +# ifndef __GNUC__ +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# ifdef _AIX +#pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif /* _AIX */ +# endif /* HAVE_ALLOCA_H */ +# endif /* _MSC_VER */ +# else /* Im a __GNUC__ happy compiler */ +#include +# endif /* __GNUC__ */ +#endif /* HAVE_ALLOCA */ + +#if !defined(NDEBUG) +#if !defined(__FILE__) +#define __FILE__ "unsupported" +#endif /* __FILE */ +#if !defined(__LINE__) +#define __LINE__ -1 +#endif /* __LINE__ */ +extern void* ftmpi_malloc( size_t, char*, int ); +extern void* ftmpi_calloc( size_t, size_t, char*, int ); +extern void* ftmpi_realloc( void*, size_t, char*, int ); +extern void ftmpi_free( void*, char*, int ); +extern void ftmpi_display_memory_usage( void ); + +#define _MALLOC(size) ftmpi_malloc( (size), __FILE__, __LINE__ ) +#define _CALLOC(nb, size) ftmpi_calloc( (nb), (size), __FILE__, __LINE__ ) +#define _REALLOC(ptr, size) ftmpi_realloc( (ptr), (size), __FILE__, __LINE__ ) +#define _FREE(ptr) ftmpi_free( (ptr), __FILE__, __LINE__ ) +#define DUMP_ALLOCATED_MEMORY() ftmpi_display_memory_usage() + +#else /* !defined(NDEBUG) */ +#include +#define _MALLOC(size) malloc((size)) +#define _CALLOC(nb, size) calloc((nb), (size)) +#define _REALLOC(ptr, size) realloc( (ptr), (size) ) +#define _FREE(ptr) free((ptr)) +#define DUMP_ALLOCATED_MEMORY() +#endif /* NDEBUG */ + +#endif /* DEBUG_H_HAS_BEEN_INCLUDED */ diff --git a/src/mca/service/stdio/snipe_lite/memory.c b/src/mca/service/stdio/snipe_lite/memory.c new file mode 100644 index 0000000000..2ed262848f --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/memory.c @@ -0,0 +1,198 @@ +#if !defined(NDEBUG) +#include +#include +#include +#include + +typedef struct __mem_allocator smemAllocator_t; + +#define VALIDATOR 0xdeadbeaf +/* #define EXTREME_DEBUG */ +#ifdef EXTREME_DEBUG +#define ZEROS_FOLLOW 1024 +#else +#define ZEROS_FOLLOW 0 +#endif /* EXTREME_DEBUG */ +#define VALUE_CHAR 0xbe + +struct __mem_allocator { + smemAllocator_t* prev; + smemAllocator_t* next; + unsigned int lineno; + unsigned int validator; + char* pFileName; + unsigned int length; + int index; +}; + +static int __alloc_index = 0; +static smemAllocator_t* pdllmem = NULL; + +#ifdef EXTREME_DEBUG +static int __overflow_detection( smemAllocator_t* pTemp ) +{ + int i; + unsigned char* pchar = ((char*)&pTemp[1]) + pTemp->length; + + for( i = 0; i < ZEROS_FOLLOW; i++ ) { + if( pchar[i] != VALUE_CHAR ) { + printf( "buffer overflow detected at position %d(%p) on memory allocated in %s at line %d (pointer %p size %d) \n", + i, pchar + i, pTemp->pFileName, pTemp->lineno, ((char*)pTemp) + sizeof(smemAllocator_t), pTemp->length ); + return -1; + } + } + return 0; +} +#endif /* EXTREME_DEBUG */ + +void* ftmpi_malloc( size_t size, char* file, int lineno ) +{ + size_t totalLength = 0; + smemAllocator_t* pTemp; + + totalLength = sizeof( smemAllocator_t ) + size + ZEROS_FOLLOW; + pTemp = (smemAllocator_t*)malloc( totalLength ); + if( pTemp == NULL ) return NULL; + pTemp->length = size; + pTemp->validator = VALIDATOR; + pTemp->pFileName = file; + pTemp->lineno = lineno; + pTemp->index = __alloc_index++; + + if( pdllmem == NULL ) { + pdllmem = pTemp; + pTemp->next = pTemp; + pTemp->prev = pTemp; + } else { + pdllmem->prev->next = pTemp; + pTemp->prev = pdllmem->prev; + pTemp->next = pdllmem; + pdllmem->prev = pTemp; + } +#ifdef EXTREME_DEBUG + memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW ); +#endif /* EXTREME_DEBUG */ + return (void*)&pTemp[1]; +} + +void* ftmpi_calloc( size_t number, size_t size, char* file, int lineno ) +{ + size_t totalLength = 0; + smemAllocator_t* pTemp; + + totalLength = sizeof( smemAllocator_t ) + number * size + ZEROS_FOLLOW; + pTemp = (smemAllocator_t*)calloc( 1, totalLength ); + pTemp->length = number * size; + pTemp->validator = VALIDATOR; + pTemp->pFileName = file; + pTemp->lineno = lineno; + pTemp->index = __alloc_index++; + + if( pdllmem == NULL ) { + pdllmem = pTemp; + pTemp->next = pTemp; + pTemp->prev = pTemp; + } else { + pdllmem->prev->next = pTemp; + pTemp->prev = pdllmem->prev; + pTemp->next = pdllmem; + pdllmem->prev = pTemp; + } +#ifdef EXTREME_DEBUG + memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW ); +#endif /* EXTREME_DEBUG */ + return (void*)&pTemp[1]; +} + +void* ftmpi_realloc( void* ptr, size_t size, char* file, int lineno ) +{ + size_t totalLength = 0; + smemAllocator_t* pTemp = (smemAllocator_t*)((char*)ptr - sizeof(smemAllocator_t)); + smemAllocator_t *prev, *next, *old; + + prev = pTemp->prev; + next = pTemp->next; + old = pTemp; + +#ifdef EXTREME_DEBUG + if( __overflow_detection( pTemp ) != 0 ) assert(0); +#endif /* EXTREME_DEBUG */ + totalLength = sizeof( smemAllocator_t ) + size + ZEROS_FOLLOW; + pTemp = (smemAllocator_t*)realloc( pTemp, totalLength ); + pTemp->length = size; + pTemp->validator = VALIDATOR; + pTemp->pFileName = file; + pTemp->lineno = lineno; + pTemp->index = __alloc_index++; + + if( pdllmem == old ) { + if( prev == old ) { + assert( next == old ); + prev = next = pTemp; + } + pdllmem = pTemp; + } + prev->next = pTemp; + next->prev = pTemp; + pTemp->prev = prev; + pTemp->next = next; +#ifdef EXTREME_DEBUG + memset( ((char*)pTemp) + sizeof(smemAllocator_t) + pTemp->length, VALUE_CHAR, ZEROS_FOLLOW ); +#endif /* EXTREME_DEBUG */ + return (void*)&pTemp[1]; +} + +void ftmpi_free( void* ptr, char* file, int lineno ) +{ + smemAllocator_t* pTemp = (smemAllocator_t*)((char*)ptr - sizeof(smemAllocator_t)); + + /* remove it from the allocated memory */ +#ifdef EXTREME_DEBUG + if( __overflow_detection( pTemp ) != 0 ) assert(0); +#endif /* EXTREME_DEBUG */ + assert( pTemp->prev->next == pTemp ); + assert( pTemp->next->prev == pTemp ); + pTemp->prev->next = pTemp->next; + pTemp->next->prev = pTemp->prev; + if( pTemp == pdllmem ) { + if( pTemp->next == pTemp ) { + assert( pTemp->prev == pTemp ); + pdllmem = NULL; + } else { + pdllmem = pTemp->next; + } + } + assert( pTemp->validator == VALIDATOR ); + pTemp->validator = 0; + /* keep this informations to see where the memory has been freed */ + pTemp->pFileName = file; + pTemp->lineno = lineno; + + /* And now really free the memory */ + free( pTemp ); +} + +void ftmpi_display_memory_usage( void ) +{ + smemAllocator_t* pTemp = pdllmem; + int totalSize = 0, chunks = 0; + + if( pTemp == NULL ) return; + printf( ">> BEGIN MEMORY USAGE and TRACE\n" ); + do { +#ifdef EXTREME_DEBUG + if( __overflow_detection( pTemp ) != 0 ) assert(0); +#endif /* EXTREME_DEBUG */ + printf( "Allocate %d bytes in file %s at line %d pointer %p index %d\n", + pTemp->length, pTemp->pFileName, pTemp->lineno, + ((char*)pTemp + sizeof(smemAllocator_t)), pTemp->index ); + chunks++; + totalSize += pTemp->length; + pTemp = pTemp->next; + } while( pTemp != pdllmem ); + printf( "Allocated %d chunks of memory with the total size of %d bytes\n", + chunks, totalSize ); + printf( ">> END MEMORY USAGE and TRACE\n" ); +} + +#endif /* NDEBUG */ diff --git a/src/mca/service/stdio/snipe_lite/msg.c b/src/mca/service/stdio/snipe_lite/msg.c new file mode 100644 index 0000000000..e42953eece --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/msg.c @@ -0,0 +1,258 @@ + +/* + HARNESS G_HCORE + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + Graham E Fagg + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#include "msgbuf.h" +#include "msg.h" +#ifdef WIN32 +#include "wincomm.h" +#else +#include "snipe_lite.h" +#endif +#include +#include +#include + +/* Note this is a simple (bad) description of a basic header */ +/* + 0-3 PKMESSAGEVER used to make sure its a packed message.. so if its not, then drop it.... if we can. + + 4-7 PACKEDMESSAGELEN length of packed data in octets (can be zero but not negative) + 8-11 SENDERS ID arbitary id that they specify + 12-15 NUMBER OF TAGS if no tags then set to zero + 16-((4*ntag)-1) individual tags ... + 16+(4*ntag)- Start of packed data. + +*/ + +/* Note to avoid using writeV etc we get a message buffer of our own JUST for packing stuff in and out of */ +/* we don't use the msgbuf routines as that effects cache coherency */ + +char hdrbuf [4096]; + + +/* this routine sends a message down a socket as a complete message */ +/* this includes a simple header (sender, tag, length) */ +/* if the free flag is set then the message buffer is freed */ +/* if free is set then even if its not send it is still freed always */ + +/* return value is either the total length sent or an error */ + +/* if the complete amount is not sent then the buffer is not freed */ + +int send_pkmesg (int send_s,int myid,int ntag,int * tagp,int buf_id,int free_buf) +/* int send_s; socket to send_s */ +/* int myid; ID I place in message header */ +/* int ntag; Number of Tags in header */ +/* int *tagp; pointer to Tags to put in header */ +/* int buf_id; message buffer I am sending or if you want to send an EMPTY message send EMPTYMSGBUF */ +/* int free_buf; non zero if you want to free the buffer up after a good send */ +{ + int len = 0; + char * buf_ptr; + int ret = -1; + int *data; + int valid; + int i; + + + if (buf_id != EMPTYMSGBUF) valid = check_buf (buf_id); + else valid = 1; + + if (!valid) return (BADBUFFER); + + if (buf_id != EMPTYMSGBUF) + get_msg_buf_info(buf_id,&buf_ptr,&len); /* get buffer info */ + else { + buf_ptr = NULL; /* if empty message */ + len = 0; + } + + data = (int*) hdrbuf; + + *data++ = htonl (PKMESSAGEVER); + *data++ = htonl (len); + *data++ = htonl (myid); + *data++ = htonl (ntag); + + for (i=0;i 0){ + ret = writeconn(send_s,buf_ptr,len); + if(ret <= 0){ + if ((buf_id != EMPTYMSGBUF)&&(free_buf)) free_msg_buf(buf_id); + return(ret); + } + else + if ((buf_id != EMPTYMSGBUF)&&(free_buf)) free_msg_buf(buf_id); + } + } + return(ret); +} + + +/* recv a packed message and return the buffer of the message / size etc */ +/* This route will allocate a buffer if it is needed (i.e. if it has a */ +/* payload). */ + +/* If there isn't enought space for all the tags it drops tags */ +/* ntags can be NULL or 0 */ +/* if there is a protocol error i.e. protocol versions don't match it bombs */ + +int recv_pkmesg (int recv_s,int * from,int * ntag,int * tagp,int * buf_id) +{ + int len; + char * buf_ptr = NULL; + int *hdata; + int *hdata2; + int size; + int ret; + int client; + int i, j; + int tmp; + int rtags; /* how many tags to receive even if it drops some */ + int tbid; /* temp buf id */ + +#ifdef VERBOSE + PRINT("Atempting to receive from %d via socket %d\n",recv_s, from); +#endif + + + /* download the data into the header buffer */ + hdata = (int*) hdrbuf; + hdata2 = (int*) hdrbuf; + + ret = readconn(recv_s,(char*)hdata,sizeof(int)*4); + if(!ret){ + return(ret); + } + + tmp = ntohl(hdata[0]); + if (tmp != PKMESSAGEVER) { /* Header check */ + #ifdef VERBOSE + printf("Recv_pkmesg has received a message with an incorrect hdr [0x%x]\n", hdata[0]); + #endif + return (MSG_BAD_HEADER); + } + + size = ntohl(hdata[1]); + client = ntohl(hdata[2]); + rtags = ntohl(hdata[3]); + +#ifdef VERBOSE + printf("header 0x%x size %d from %d ntags %d\n", + tmp, size, client, rtags); +#endif + + /* now we have a copy of the header we can overwrite the headerbuffer */ + + /* download the message tags into the header buffer */ + if (rtags>0) { + hdata2 = (int*) hdrbuf; + ret = readconn(recv_s,(char*)hdata2,sizeof(int)*rtags); + if(!ret){ + return(ret); + } + } + + /* ok copy over the ones we have been given space for */ + /* check to see if we are even excepting tags first ! */ + if (ntag) { + j = *ntag; + if (j>rtags) j=rtags; + + for(i=0;i + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#ifndef _GHCORE_MSG_H +#define _GHCORE_MSG_H 1 + + +#define EMPTYMSGBUF -1812 +#define MSG_BAD_HEADER -1111 + +#define PKMESSAGEVER 0xABCD + + +int send_pkmesg (int send_s,int myid,int ntag,int * tagp,int buf_id,int free_buf); +int recv_pkmesg (int recv_s,int * from,int * ntag,int * tagp,int * buf_id); + +#endif /* _GHCORE_MSG_H */ diff --git a/src/mca/service/stdio/snipe_lite/msgbuf.h b/src/mca/service/stdio/snipe_lite/msgbuf.h new file mode 100644 index 0000000000..71ed9bacb7 --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/msgbuf.h @@ -0,0 +1,155 @@ + +/* + HARNESS G_HCORE + HARNESS FT_MPI + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + Graham E Fagg + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +#ifndef _GHCORE_MSGBUF_H +#define _GHCORE_MSGBUF_H 1 + + + +/* + message packing/unpacking routines + +*/ + + +/* Uncomment the following line to enable msgbuf V2.0 */ +#define MSG_BUF_V2 + + + + +#ifdef MSG_BUF_V2 + +#define _msg_resize_buf _hn_msg_resize_buf +#define init_msg_bufs hn_init_msg_bufs +#define dump_msg_bufs hn_dump_msg_bufs +#define check_buf hn_check_buf +#define get_msg_buf_info hn_get_msg_buf_info +#define get_msg_buf hn_get_msg_buf +#define set_unpksize hn_set_unpksize +#define get_msg_buf_of_size hn_get_msg_buf_of_size +#define free_msg_buf hn_free_msg_buf +#define end_msg_buf hn_end_msg_buf + +#define pk_int8 hn_pk_int8 +#define pk_int16 hn_pk_int16 +#define pk_int32 hn_pk_int32 +#define pk_raw32 hn_pk_raw32 +#define pk_int64 hn_pk_int64 +#define pk_int128 hn_pk_int128 +#define pk_real32 hn_pk_real32 +#define pk_real64 hn_pk_real64 +#define pk_byte hn_pk_byte +#define pk_string hn_pk_string + +#define upk_int8 hn_upk_int8 +#define upk_int16 hn_upk_int16 +#define upk_int32 hn_upk_int32 +#define upk_raw32 hn_upk_raw32 +#define upk_int64 hn_upk_int64 +#define upk_int128 hn_upk_int128 +#define upk_real32 hn_upk_real32 +#define upk_real64 hn_upk_real64 +#define upk_byte hn_upk_byte +#define upk_string hn_upk_string + + +#endif + + + + + + + + + + +int init_msg_bufs (); /* must call first */ +int get_msg_buf_info (int buf,char ** base,int * len); /* get info on buf */ +int get_msg_buf (int resizable ); /* get a free buf */ +int get_msg_buf_of_size (unsigned long reqsize,int resize,int setunpksize); /* get a free buf that is a particular size */ +int free_msg_buf (int buf); /* free a buf */ +int check_buf (int buf); /* valid buf ? */ +int dump_msg_bufs (); /* dump msg buf information */ +int end_msg_buf (); /* free ALL bufs */ + +/* pack and unpack binary data */ +int pk_byte (int buf,void * ptr,long n); +int upk_byte (int buf,void * ptr,long n); +int pk_raw32 (int buf,void * ptr,long n); +int upk_raw32 (int buf,void * ptr,long n); + +/* pack basic integer types */ + +int pk_int8 (int buf,void * ptr,long n); +int pk_int16 (int buf,void * ptr,long n); +int pk_int32 (int buf,void * ptr,long n); +int pk_int64 (int buf,void * ptr,long n); +int pk_int128 (int buf,void * ptr,long n); + +/* pack real numbers */ +int pk_real32 (int buf,void * ptr,long n); +int pk_real64 (int buf,void * ptr,long n); + +/* unpack basic integer types */ + +int upk_int8 (int buf,void * ptr,long n); +int upk_int16 (int buf,void * ptr,long n); +int upk_int32 (int buf,void * ptr,long n); +int upk_int64 (int buf,void * ptr,long n); +int upk_int128 (int buf,void * ptr,long n); + +/* unpack real numbers */ +int upk_real32 (int buf,void * ptr,long n); +int upk_real64 (int buf,void * ptr,long n); + +/* handles strings */ +/* note this takes NULL terminated strings and returns null terminated strings */ + +int pk_string (int buf,char *strptr); +int upk_string (int buf,void * strptr,long maxlen); + +/* error codes (i.e. rather than just -1) */ +#define BADBUFFER -2010 /* bad buffer id */ +#define OUTOFBUFFERS -2011 /* no free msg buffers free */ +#define OUTOFMEMORY -2012 /* cannot allocate any more memory for message buffers */ +#define BADLUCK -13 /* no comment */ +#define BADPARM -2014 /* other parameters are bad/invalid pointers */ +#define BADDATA -2015 /* to/from data addr is bad (null etc) */ + + +#endif /* _GHCORE_MSGBUF_H */ diff --git a/src/mca/service/stdio/snipe_lite/msgbuf2.c b/src/mca/service/stdio/snipe_lite/msgbuf2.c new file mode 100644 index 0000000000..ddd33f3a67 --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/msgbuf2.c @@ -0,0 +1,1762 @@ + +/* + HARNESS G_HCORE + HARNESS FT_MPI + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: + Thara Angskun + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + + +/* msg buffer handling routines */ + +/* + message packing/unpacking routines + +*/ + + + +#include +#include +#include +#include "msgbuf.h" +#include "debug.h" + +/****************************/ +/* message buffer version 2 */ +/****************************/ + +/* Message buffer V2 should called with prefix "hn" */ +/* to avoid conflict with other program such as intel testsuite */ + + +/*** WARNING!!! : (for backward compatability) */ + +/* some function return value >=0 is success, negative number is error */ +/* some function return value >=1 is success, 0 and negative number is error */ +/* Please see comment above each function */ + +/* OK, Let's me put it this way.... Double standard ? ;-) */ + +/* The following function, negative number is error */ +/* - _hn_msg_resize_buf */ +/* - hn_dump_msg_buf */ +/* - hn_set_unpksize */ +/* - hn_get_msg_buf_of_size */ +/* - hn_free_msg_buf */ +/* - hn_end_msg_buf */ + +/* The following function, zero and negative number is error */ +/* - hn_init_msg_buf */ +/* - hn_check_buf */ +/* - hn_get_msg_buf_info */ +/* - hn_pk_* */ +/* - hn_upk_* */ + +typedef struct { + void* base_ptr; /* start of my memory */ + void* data_ptr; /* location of where next data will go */ + void* from_ptr; /* location of where to get the next data from */ + long size; /* size of buffer */ + long len; /* total amount already packed */ + long space; /* size - len */ + long toend; /* how many bytes till the end when unpacking :) */ +} msg_cb_t; + +int num_entry=0; /* current number of entry */ +int lowest_free_entry=0; /* lowest entry free slot */ +int msg_convert_type; /* message conversion type */ +int msg_buf_init_called = 0; /* do we call init? */ +msg_cb_t *msg_buf; + + + + +/** +_hn_msg_resize_buf - resize buffer (Internal) +@param buf buffer ID +@param incsize increase size +@retval <0 error +@param >=0 bufID +*/ +int _hn_msg_resize_buf (int buf,long incsize ) +{ + +char *p; +char *q; +char *oldp; +long oldsize; +long oldlen; +long oldspace; +long difffrom; /* if this has been read from at all, whats its offset */ +long reqsize; + +/* printf("[%s:%d] Incsize is %ld\n",__FILE__,__LINE__,incsize); fflush(stdout); */ + + /* remember what we are doing */ + oldp = (char*)msg_buf[buf].base_ptr; + oldsize = msg_buf[buf].size; + oldlen = msg_buf[buf].len; + oldspace = msg_buf[buf].space; + difffrom = ((char*)msg_buf[buf].from_ptr - (char*)msg_buf[buf].base_ptr); + + + reqsize = oldsize + incsize; + + p = _REALLOC(oldp,reqsize); + /* realloc is faster than malloc and loop pointer in case that we don't need to reallocate new space */ + /* Time on pack 10000 integer, realloc = 3052 micro sec, malloc + loop = 1915754 micro sec */ + + #ifdef OLDMALLOC + + p = (char*) _MALLOC (reqsize); + if (!p) { + /* ops, we have a problem houston */ + return (-1); + } + + /* else we have the memory, so lets do it */ + + /* first copy the data over */ + + q = p; /* make a copy of the new start pointer */ + + memcpy( q, oldp, oldlen ); + if(msg_buf[buf].base_ptr) _FREE (msg_buf[buf].base_ptr); /* free the old memory first */ + + #endif + + /* note, q = location of next free location in the new object */ + q = p + oldlen; + + msg_buf[buf].base_ptr = p; + msg_buf[buf].data_ptr = q; + msg_buf[buf].from_ptr = (char*)msg_buf[buf].base_ptr + difffrom; + msg_buf[buf].size = reqsize; + msg_buf[buf].len = oldlen; + msg_buf[buf].space = oldspace + incsize; + + return (buf); +} + +/** +hn_init_msg_bufs - Initialize message buffer +*/ +int hn_init_msg_bufs(void) +{ +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + + if (msg_buf_init_called) return 1; + else msg_buf_init_called = 1; + +#if defined (IMA_SUN4) || defined (IMA_SUN4SOL2) || defined (IMA_JAVA) || defined (IMA_AIX4) || defined (IMA_RS6K) || defined (IMA_SGI6) || defined (IMA_SP2) + msg_convert_type = 0; +#else + msg_convert_type = 1; +#endif + return 1; +} + +/** +hn_dump_msg_bufs - Display message buffer +*/ +int hn_dump_msg_bufs () +{ + int i; +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + + puts("----------------------------------------"); + puts("Internal Message Buffer Information Dump"); + puts("----------------------------------------"); + + if(num_entry > 0) { + printf(" ID\tBase\tSize\tLength\tSpace\tToEnd\n"); + for(i=0;i=num_entry) { +#ifdef VERBOSE + printf("[%s:%d] buffer ID more than or equal number of entry\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + return (1); +} + + +/** +hn_check_buf - check buffer validity +@param buf buffer ID +@retval 0 Invalid buffer +@retval 1 Valid buffer +*/ +int hn_check_buf (int buf) +{ + if (hn_check_buf_basic(buf) <=0) return 0; + + if (msg_buf[buf].size <= 0) { +#ifdef VERBOSE + printf("[%s:%d] This buffer doesn't use anymore (buf %d,size %d)\n",__FILE__,__LINE__,buf,msg_buf[buf].size); + fflush(stdout); +#endif + return (0); + } + return (1); +} + +/** +hn_get_msg_buf_info - get message buffer information +@param buf buffer ID +@param base base memory address [OUTPUT] +@param len buffer length [OUTPUT] +@retval 1 success +@retval 0 error +*/ +int hn_get_msg_buf_info (int buf,char ** base,int * len) +{ +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + + if (!base) { +#ifdef VERBOSE + printf("[%s:%d] Invalid base parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + if (!len) { +#ifdef VERBOSE + printf("[%s:%d] Invalid len parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + *base = (char*) msg_buf[buf].base_ptr; + *len = msg_buf[buf].len; + return (1); +} + +/** +hn_set_unpksize - set unpack size +@param buf buffer ID +@param reqsize request size +@retval 0 success +@retval -1 error +*/ +int hn_set_unpksize (int buf,int reqsize) +{ +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return -1; + } + if (reqsize < 0) { +#ifdef VERBOSE + printf("[%s:%d] Invalid reqsize parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return -1; + } + msg_buf[buf].toend = reqsize; + return 0; +} + +/** +hn_get_msg_buf_of_size - get message buffer of specify size +@param reqsize request size +@param resize [OBSOLETE - for backward compatibility only!!] +@param setunpacksize - set unpack size (toend) to the request size +@retval >=0 buffer ID +@retval <0 error +*/ +int hn_get_msg_buf_of_size (unsigned long reqsize,int resize,int setunpksize) +{ + int bufid; + int j; + char * p; +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + + if (reqsize <= 0) { +#ifdef VERBOSE + printf("[%s:%d] Invalid reqsize parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return -1; + } + + if(lowest_free_entry==num_entry) { + bufid=num_entry; + num_entry++; + lowest_free_entry++; + if(bufid==0) { + msg_buf=(msg_cb_t *)_MALLOC(sizeof(msg_cb_t)); + } else { + msg_buf=(msg_cb_t *)_REALLOC(msg_buf,sizeof(msg_cb_t)*num_entry); + } + } else { + bufid=lowest_free_entry; + } + + p = (char *)_MALLOC(reqsize); + if (!p) { +#ifdef VERBOSE + printf("[%s:%d] Cannot allocate memory !!\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (-1); + } + + /* + if(msg_buf[bufid].base_ptr) _FREE (msg_buf[bufid].base_ptr); + */ + + msg_buf[bufid].base_ptr = p; + msg_buf[bufid].data_ptr = p; + msg_buf[bufid].from_ptr = p; + msg_buf[bufid].size = reqsize; + msg_buf[bufid].len = 0; + msg_buf[bufid].space = reqsize; + + for(j=lowest_free_entry;j=0 buffer ID +@retval <0 error +*/ +int hn_get_msg_buf (int resizable ) +{ + /* just return 1 byte buffer for now */ +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + return hn_get_msg_buf_of_size(10,resizable,0); +} + + +/** +hn_free_msg_buf - Free message buffer +@param buf buffer ID +@param <0 error +@param >=0 success +*/ +int hn_free_msg_buf (int buf) +{ + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf_basic(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return -1; + } + if(buf < lowest_free_entry) lowest_free_entry = buf; + + if(msg_buf[buf].base_ptr!=NULL) { + _FREE(msg_buf[buf].base_ptr); + msg_buf[buf].base_ptr=NULL; + } + + msg_buf[buf].data_ptr = NULL; + msg_buf[buf].from_ptr = NULL; + msg_buf[buf].len = 0; + msg_buf[buf].size = 0; + msg_buf[buf].space = 0; + msg_buf[buf].toend = 0; + + return (buf); +} + +/** +hn_end_msg_buf - End message buffer +@param buf buffer ID +@param <0 error +@param >=0 success +*/ +int hn_end_msg_buf (void) +{ + int i; +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + for (i=0;i0 success +*/ +int hn_pk_int8 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 1*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + /* ok have space.. so do it */ + /* No msg_convert_type check for bytes */ + + for(i=0;i0 success +*/ +int hn_pk_int16 (int buf,void * ptr,long n) +{ +int i; +char *p; +char *q; +int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 2*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + /* ok have space.. so do it */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_int32 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + /* ok have space.. so do it */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_raw32 (int buf,void * ptr,long n) +{ +int i; +char *p; +char *q; +int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + for(i=0;i0 success +*/ +int hn_pk_int64 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 8*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_int128 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 16*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_real32 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_real64 (int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + int s; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 8*n; + + if (msg_buf[buf].space < s) { /* not enough space */ + i = _hn_msg_resize_buf (buf, s); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_pk_byte(int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if (msg_buf[buf].space < n) { /* not enough space */ + i = _hn_msg_resize_buf (buf, n); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) ptr; + + for(i=0;i0 success +*/ +int hn_pk_string (int buf,char *strptr) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if(!strptr) { +#ifdef VERBOSE + printf("[%s:%d] Invalid strptr parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + /* What's happen if the string is not NULL terminated?. Yep.. call 911 */ + + s = strlen (strptr); + if(s<=0) { +#ifdef VERBOSE + printf("[%s:%d] The string is not NULL terminated or NULL string\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + +#ifdef VERBOSE9 + printf("[%s:%d] If you see this number -> [%d] \"strange\". Your string is not NULL terminated. \n",__FILE__,__LINE__,s); + fflush(stdout); +#endif + + /* plus 4 for the lenght of string */ + + if (msg_buf[buf].space < (s+4)) { /* not enough space */ + i = _hn_msg_resize_buf (buf, (s+4)); /* request a resize on it */ + if (i<0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to resize\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); /* i.e. it failed to resize, so no data packed */ + } + } + + if(hn_pk_int32 (buf, &s, 1) <=0) { +#ifdef VERBOSE + printf("[%s:%d] Failed to pack lenght of string [%d]\n",__FILE__,__LINE__,s); + fflush(stdout); +#endif + return (0); + } + + p = (char *) msg_buf[buf].data_ptr; + q = (char *) strptr; + + /* memcopy oneday */ + for(i=0;i0 success +*/ +int hn_upk_int8 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 1*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_int16 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 2*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_int32 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_raw32 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + /* note we step through here 's' times not 'n' times */ + for(i=0;i0 success +*/ +int hn_upk_int64 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 8*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_int128 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 16*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + /* ok unpack it.. make it so */ + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_real32 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 4*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_real64 (int buf,void * ptr,long n) +{ + int i; + int s; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + s = 8*n; + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + if (msg_convert_type) { + for (i=0;i0 success +*/ +int hn_upk_byte(int buf,void * ptr,long n) +{ + int i; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if (msg_buf[buf].toend < n) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + p = (char *) ptr; + q = (char *) msg_buf[buf].from_ptr; + + for(i=0;i0 success +*/ +int hn_upk_string (int buf,void * strptr,long maxlen) +{ + int i; + int s; + int t; + char *p; + char *q; + +#ifdef VERBOSE + printf("[%s:%d] CALLING %s\n",__FILE__,__LINE__,__FUNCTION__); +#endif + if (!hn_check_buf(buf)) { +#ifdef VERBOSE + printf("[%s:%d] Invalid buf parameter\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if(hn_upk_int32(buf, &s, 1) <=0 ) { +#ifdef VERBOSE + printf("[%s:%d] Cannot unpack length of the string\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if (msg_buf[buf].toend < s) { /* not enough space */ +#ifdef VERBOSE + printf("[%s:%d] The space is not enough, Die another day.\n",__FILE__,__LINE__); + fflush(stdout); +#endif + return (0); + } + + if ((s+1)>maxlen) { /* the +1 and -1 are for the NULL characters we will terminate the string with */ + t = maxlen-1; + } else { + /* s stays the same */ + t = s; /* no truncated message to chop off later */ + } + + p = (char *) strptr; + q = (char *) msg_buf[buf].from_ptr; + + /* memcopy oneday */ + for(i=0;i + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + +/* + SNIPE_LITE was part of the SNIPE experimental metacomputing system + + the comms library was a non threaded 'get the message there' TCP + library that is a little more carefull than the cs340 socketfun stuff + + Incept for this code was in 1998. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "syslog.h" + +#ifdef __sun +#include +#endif + +#include "snipe_lite.h" +#include "syslog.h" + +#define RETRIES 2 + +extern int errno; + +static char* default_name = NULL; +static int host_addr = 0; + +syslog_t* slsyslog = NULL; + +/* now that we have included everything under the Sun... */ +/* and I won't mention Sun TLI problems here */ + +/* moved to snipe_lite.h, since these routines are also + acces from snipe2.c */ +/* void nodelay();*/ /* hack routine to improve performance.. maybe */ +/* void setnonblocking();*/ /* sets the given socket non-blocking */ +/* void setblocking(); *//* sets the given socket blocking again */ +/* int setsendrecvbufs();*/ /* Sets send/recv buffer sizes */ + + +int setportconn (int *s,int port,int range) +/* returns final port value or error */ +/* int *s; socket server uses.. this is created here */ +/* int port; initial port we make service on. */ +/* int range; range of ports */ +{ + struct sockaddr_in sa; + int ts; + int i; + int rc = 0; + int p; + + p = port; + ts = socket (AF_INET, SOCK_STREAM, 0); /* yuck */ +#ifdef VERBOSE + printf("Socket [%d]\n", ts); +#endif /* VERBOSE */ + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = INADDR_ANY; + + for( i = 0; i <= range; i++ ) { + sa.sin_port = htons (p); /* convert just to be safe */ + rc = bind( ts, (struct sockaddr *)&sa, sizeof (sa) ); +#ifdef VERBOSE + printf ("Bind on socket [%d] port [%d] = [%d]\n", ts, p, rc); + if (rc) perror("Bind()"); +#endif /* VERBOSE */ + + if (!rc) { /* i.e. a valid port was found */ +#ifdef VERBOSE + printf("Attempting listen after bind on socket [%d]\n", ts); +#endif /* VERBOSE */ + setsendrecvbufs( ts, 128 ); /* TODO check if it's really useful */ + rc = listen (ts, LISTENBACKLOG); /* handle 5 possible connection at once */ +#ifdef VERBOSE + printf("Listen on socket [%d] = [%d]\n", rc); + if (rc) perror ("Listen()"); +#endif /* VERBOSE */ + if (rc) break; /* i.e. error */ + /* else */ + *s = ts; /* return socket value as well */ + return (p); + } + + /* if ((rc!=EADDRINUSE)&&(rc!=EADDRNOTAVAIL)&&(rc!=EACCES)) { */ + /* for now we ignore this... yes we do */ + /* } */ + + /* port was unavailable so */ + p++; /* look at the next one */ + } + + /* ok.. we didnot find one */ + close (ts); + *s = 0; /* return no socket */ + return (rc); /* which is negative and the last bind return code */ +} + +int allowconn (int s,int fe,int * spid) +/* int s; socket we listen on */ +/* int fe; Fork Enabled? 0=no 1=yes */ +/* If enabled then forks new process on accept */ +/* int *spid; new process id handling the returned socked */ +/* used by multitasking servers */ +{ + int s2; /* new socket */ + /* struct sockaddr *new_s_addr_ptr; */ + struct sockaddr new_s_addr; + /* socklen_t */ int new_s_addr_len; + + new_s_addr_len = sizeof (new_s_addr); +#ifdef VERBOSE + printf("Allowing connections on socket [%d]\n", s);fflush(stdout); +#endif /* VERBOSE */ + /* s2 = accept (s, new_s_addr_ptr, &new_s_addr_len); */ + + /* make sure the socket is a blocking socket i.e. hasn't been probe'd */ + setblocking (s); + accept_again: + s2 = accept (s, &new_s_addr, &new_s_addr_len); + if (s2<0) { + if( errno == EINTR ) { + /* interrupted by a signal */ + goto accept_again; + } +#ifdef VERBOSE + printf("Accept on socket [%d] failed as [%d]\n", s, s2); + perror ("Accept()"); +#endif /* VERBOSE */ + return (s2); + } +#ifdef VERBOSE + printf("Accepted connection on socket [%d] as new socket [%d]\n", s, s2); +#endif /* VERBOSE */ + + nodelay(s2); + return (s2); +} + +/* Probe conn is a non blocking version of allowconn() */ +int probeconn (int s,int fe,int * spid) +/* int s; socket we listen on */ +/* int fe; Fork Enabled? 0=no 1=yes */ +/* If enabled then forks new process on accept */ +/* int *spid; new process id handling the returned socked */ +/* used by multitasking servers */ +{ + int s2; /* new socket */ + /* struct sockaddr *new_s_addr_ptr; */ + struct sockaddr new_s_addr; + /* socklen_t */ int new_s_addr_len; + int rc; + + new_s_addr_len = sizeof (new_s_addr); +#ifdef VERBOSE + printf("Allowing connections on socket [%d]\n", s); +#endif /* VERBOSE */ + /* s2 = accept (s, new_s_addr_ptr, &new_s_addr_len); */ + /* make the socket non blocking for the probe to work */ + /* setnonblocking (s); */ + + /* now just check using poll which should be faster */ + rc = pollconn (s, 0, 0); + + if (!rc) return (0); + if (rc>0) { + s2 = accept (s, &new_s_addr, &new_s_addr_len); +#ifdef VERBOSE + printf("Accept returned [%d][0x%x]\n", s2, s2); +#endif /* VERBOSE */ + + if (s2<0) { + /* printf("Accept on socket [%d] failed as [%d]\n", s, s2); */ + /* printf("Errno is %d\n", errno); */ + /* printf("EWOULDBLOCK = %d\n", (int) EWOULDBLOCK); */ + /* as this is non-blocking printing the below is wrong as its not an */ + /* error, but an unavilable connection */ + /* perror ("Accept()"); */ + /* close (s2); */ + /* not that it was open in the first place */ + /* be nice and make the return value 0 ? */ + /* s2 = 0; */ + /* return (s2); */ + /* setnonblocking (s); */ + /* return it back to blocking */ + return (0); + } +#ifdef VERBOSE + printf("Accepted connection on socket [%d] as new socket [%d]\n", s, s2); +#endif /* VERBOSE */ + + /* make the new socket blocking by default */ + setblocking (s2); + + /* set tcpnodelay as well */ + nodelay(s2); + + return (s2); + } + + if (rc<0) return (rc); /* return error code if poll had a problem */ + return 0; +} + +int getconn (char * host,int * port,int search) +/* char *host; full name of host running service */ +/* int *port; port where service is running */ +/* note this is also a return value */ +/* int search; range allowed for port search */ +{ + struct sockaddr_in sa_in; + int target_port; + struct hostent *hp; + int ts; + int rc = 0; + + target_port = *port; /* get start point */ + + hp = gethostbyname (host); + if(hp==NULL) { /* cannot resolve hostname */ + return -1; + } + +#ifdef IMA_SGI6 + memcpy ( &sa_in.sin_addr, hp->h_addr, hp->h_length); +#else + { + u_long target_s_addr; + bcopy(hp->h_addr, (char *)&target_s_addr, hp->h_length); + sa_in.sin_addr.s_addr = target_s_addr; + } +#endif + + sa_in.sin_family = AF_INET; + + while (search>=0) { + ts = socket (AF_INET, SOCK_STREAM, 0); /* yuck */ + /* try a new socket each time? */ + sa_in.sin_port = htons (target_port); /* convert just to be safe */ + /* hope I can keep reusing this struct */ + + rc = connect (ts, (struct sockaddr *) &sa_in, sizeof(sa_in)); + if( rc == 0 ) { /* success */ + *port = target_port; /* tell them the port used */ + nodelay(ts); + return (ts); /* give them the socket */ + } else { /* failure */ +#if !defined(NDEBUG) + fprintf( stderr, "Connect failed with host %s port %d (%s)\n", + host, target_port, strerror(errno) ); +#endif /* NDEBUG */ + target_port++; /* look at the next port */ + search--; /* one less attempt left */ + /* I belive ts is now defunted.. so I close it?? */ + close (ts); + } + } /* while */ + + /* well we are here so fidles.. */ + return (rc); + +} + + +int getconn_addr (unsigned long addr,int * port,int search) +/* unsigned long addr; sa_addr of host running service */ +/* int *port; port where service is running */ +/* note this is also a return value */ +/* int search; range allowed for port search */ +{ + struct sockaddr_in sa_in; + int target_port; + int ts; + int rc = 0; + + sa_in.sin_addr.s_addr = addr; + sa_in.sin_family = AF_INET; + + target_port = *port; /* get start point */ + + while( search >= 0 ) { + ts = socket (AF_INET, SOCK_STREAM, 0); /* yuck */ + /* try a new socket each time? */ + sa_in.sin_port = htons (target_port); /* convert just to be safe */ + /* hope I can keep reusing this struct */ + + rc = connect (ts, (struct sockaddr *) &sa_in, sizeof(sa_in)); + + if (!rc) { /* success */ + *port = target_port; /* tell them the port used */ + nodelay(ts); + return (ts); /* give them the socket */ + } + /* failure */ + WARNING( LOG_CONN, "Connection failed to node %s on port %d\n", + inet_ntoa(sa_in.sin_addr), target_port ); + target_port++; /* look at the next port */ + search--; /* one less attempt left */ + /* I belive ts is now defunted.. so I close it?? */ + close (ts); + } /* while */ + + /* well we are here so fidles.. */ + return (rc); +} + +int closeconn (int s) +/* int s; socket to close, also notifies the other party */ + +{ + /* too tired */ + return close (s); +} + + +int pollconn (int s,int dir,int tout) /* checks for in/out events on a socket */ +/* int s; */ +/* int dir; direction 0 = read, 1 = write, -1 for error detect */ +/* int tout; */ +{ + struct pollfd pfd; + /* int tout; */ + int rc; + + if (tout<0) tout = 10; /* default to (10ms) if a bad arg */ + + /* OK, pack the poll data struct */ + pfd.fd = s; + /* select events depending on situation */ + pfd.events = POLLIN; + if (dir>0) pfd.events |= POLLOUT; /* look to write */ + + pfd.revents = 0; + + /* ok, kick it in the arse and let it go */ + rc = poll (&pfd, 1, tout); + if( rc >= 0 ) { + /* zero means nothing relevant on the socket, and >0 one event ready */ + return rc; + } + /* now we get a negative return code from poll */ + if( errno == EINTR ) return 0; /* dont be messy, it's not really an error */ + DUMP_SOCKET_ERROR( s, errno ); + return -1; +} + + + +int writeconn (int s,char * data,int len)/* sends stream data. I.e. no header/seq stuff */ +/* return value = len or error */ +/* int s; socket conn is on */ +/* char *data; raw data to send */ +/* int len; length of data to send */ +{ + int i; + int tosend, gone, fluffed; /* loop variables */ + + + tosend = len; + gone = 0; /* just in case */ + fluffed = 0; /* just in case */ + + for (i=0;tosend>0;) { +#ifdef DB9 + printf("Write loop for socket [%d]. Sent [%d] / [%d] or [%d] left.\n", + s, i, len, tosend); +#endif /* DB9 */ + + gone = write (s, &data[i], tosend); + +#ifdef DB9 + printf("wrote [%d] byte on socket [%d].\n", gone, s); +#endif /* DB9 */ + if (gone<=0) { + fluffed++; +#ifdef VERBOSE + if (gone<0) perror ("Write()"); +#endif /* VERBOSE */ + if (fluffed==RETRIES) { + DUMP_SOCKET_ERROR(s, errno); + fprintf(stderr,"%s:%d Problem, connection on socket [%d] has failed.\nThis connect has been closed.\n", __FILE__, __LINE__, s); + fflush(stderr); + close (s); + return (i); /* how much we sent in the end... */ + /* upto the user app to realise the error. */ + } /* if fluffed */ + } + else { /* i.e. we sent some */ + i+= gone; /* total sent and index ptr update */ + tosend -= gone; + fluffed = 0; /* fluffed reset counter */ + } /* if gone */ + } /* for look on tosend */ + + + /* ok all done... now return amount wrote */ + return (i); + + +} + +int readconn (int s,char * data,int len)/* reads stream data. I.e. no header/seq stuff */ +/* return is read length or error */ +/* int s; socket conn is on */ +/* char *data; raw data buffer */ +/* int len; length of data tobe read */ +{ + int i; + unsigned int toget; /* note type */ + int got, fluffed; /* loop variables */ + + toget = (unsigned) len; + fluffed = 0; + +#ifdef DB9 + printf("read on [%d] to get msg length [%d]\n", s, toget); +#endif + + for (i=0;toget>0;) { +#ifdef DB9 + printf("Reading on [%d] amount [%d]\n", s, toget); +#endif /* DB9 */ + + got = read (s, &data[i], toget); + +#ifdef DB9 + printf("reading on [%d] got [%d] bytes.\n", s, got); +#endif /* DB9 */ + + if (got<=0) { + fluffed++; + if (fluffed==RETRIES) { +#if !defined(NDEBUG) + fprintf(stderr,"%s:%d Problem, connection on socket [%d] has failed.\nThis connect has been closed.\n", __FILE__, __LINE__, s); +#endif /* NDEBUG */ + close (s); + return (i); /* how much we got in the end... */ + /* upto the user app to realise the error. */ + } /* if fluffed */ + } + else { /* i.e. we got */ + i+= got; /* total got and index ptr update */ + toget -= got; + fluffed = 0; /* fluffed reset counter */ + } /* if got */ + } /* for look on toget */ + + /* ok all done... now return amount read */ + return (i); + + + +} + + +int writemsgconn (int s,char * data,int len)/* sends message data. I.e. header & seq */ +/* return value = len or error */ +/* int s; socket conn is on */ +/* char *data; raw data to send */ +/* int len; length of data to send */ +{ + int i; + int n; + unsigned int nblen; /* networkbyte message length */ + int tosend, gone, fluffed; /* loop variables */ + + nblen = (unsigned int) htonl (len); /* message length for the header */ +#ifdef DB9 + printf("Attempting message write on [%d] for msg of len [%d]\n", s, len); +#endif + + /* write outgoing message length */ + n = write (s, &nblen, sizeof(unsigned int)); /* ek */ + + if(n!=sizeof(int)) { return (-100); } /* ok thats a bad way to do it! */ +#ifdef DB9 + printf("wrote on socket [%d] message hdr.\n", s); +#endif + + + + tosend = len; + gone = 0; /* just in case */ + fluffed = 0; /* just in case */ + + for (i=0;tosend>0;) { +#ifdef DB9 + printf("Write loop for socket [%d]. Sent [%d] / [%d] or [%d] left.\n", + s, i, len, tosend); +#endif /* DB9 */ + + gone = write (s, &data[i], tosend); + +#ifdef DB9 + printf("wrote [%d] byte on socket [%d].\n", gone, s); +#endif /* DB9 */ + + if (gone<=0) { + fluffed++; +#ifdef VERBOSE + if (gone<0) perror ("Write()"); +#endif /* VERBOSE */ + if (fluffed==RETRIES) { + fprintf(stderr,"%s:%d Problem, connection on socket [%d] has failed.\nThis connect has been closed.\n", __FILE__, __LINE__, s); + fprintf( stderr, "write %d from %d bytes\n", i, len ); + close (s); + return (i); /* how much we sent in the end... */ + /* upto the user app to realise the error. */ + } /* if fluffed */ + } + else { /* i.e. we sent some */ + i+= gone; /* total sent and index ptr update */ + tosend -= gone; + fluffed = 0; /* fluffed reset counter */ + } /* if gone */ + } /* for look on tosend */ + + + /* ok all done... now return amount wrote */ + return (i); + +} + + +int readmsgconn (int s,char * data,int mlen)/* reads message data. I.e. header & seq */ +/* return value = len or error */ +/* int s; socket conn is on */ +/* char *data; raw data buffer */ +/* int mlen; max length of data buffer */ +{ + int readed = 0; + int n; + char junk[512]; /* used as temporary trash */ + unsigned int ilen, nbilen; /* incomming message length */ + unsigned int tojunk, toget; /* note type */ + int got, fluffed; /* loop variables */ + + fluffed = 0; + readed = 0; + + /* read incomming message length */ + n = read (s, &nbilen, sizeof(unsigned int)); /* ek */ + if( n != sizeof(int) ) { return (-100); } /* ok thats a bad way to do it! */ + + ilen = (unsigned int) ntohl (nbilen); /* convert from network byte format */ + if( ilen > mlen ) { /* buffer too small.. will have to truncate. */ + /* Note we don't read ahead or anything fancy */ + tojunk = ilen - mlen; + toget = mlen; + } else { + tojunk = 0; + toget = ilen; + } +#ifdef DB9 + printf("read on [%d] total msg length [%d] overrun [%d]\n", s, toget, tojunk); +#endif + + while( toget > 0 ) { + got = read (s, &data[readed], toget); + if( got < 0 ) { + if( (errno == EAGAIN) || (errno == EINTR) ) continue; + if( (++fluffed) == RETRIES ) { + fprintf(stderr,"%s:%d Problem, connection on socket [%d] has failed.\nThis connect has been closed.\n", __FILE__, __LINE__, s); + goto report_error; + } /* if fluffed */ + } + readed += got; /* total got and index ptr update */ + toget -= got; + fluffed = 0; /* fluffed reset counter */ + } /* for look on toget */ + + /* now for the truncate bit. */ + while( tojunk > 0 ) { + got = ( tojunk < 512 ? tojunk : 512 ); + got = read( s, junk, got ); + if( got < 0 ) { /* error on read check for normall interrupt */ + if( (errno == EINTR) || (errno == EAGAIN) ) continue; + fprintf(stderr,"%s:%d Problem, connection on socket [%d] has failed.\nThis connect has been closed.\n", __FILE__, __LINE__, s); + goto report_error; + } + tojunk -= got; + } + /* ok all done... now return amount read */ + return readed; + report_error: + /* upto the user app to realise the error. */ + close( s ); + return readed; +} + +/* this routine sets the socket to no delay */ +void nodelay(int s) +{ +#ifdef NODELAYALLOWED + int one=1; /* spotted by Rainer Keller in Stuttgart */ + struct protoent *p; + p = getprotobyname("tcp"); + /* if( p && setsockopt(s, p->p_proto, TCP_NODELAY, &one, sizeof(one)) < 0) */ + if( p && setsockopt(s, p->p_proto, TCP_NODELAY, (char*)&one, sizeof(one)) < 0) + perror("setsockopt: nodelay"); +#else + /* printf("TCPNODELAY ignored\n"); */ +#endif /* NODELAYALLOWED */ +} + +void setnonblocking(int s ) /* sets the given socket non-blocking */ +{ + int i; + i = fcntl (s, F_GETFL, 0); +#ifdef VERBOSE + printf("FL on [%d] = %d\n", s, i); +#endif /* VERBOSE */ + i = i | O_NONBLOCK; /* mark it as non blocking */ +#ifdef VERBOSE + printf ("O_NONBLOCK = %d\n", O_NONBLOCK); +#endif /* VERBOSE */ + (void)fcntl (s, F_SETFL, i); +#ifdef VERBOSE + printf("New FL [%d] on [%d] returns [%d]\n", i, s, j); +#endif /* VERBOSE */ +} + +void setblocking(int s ) /* sets the given socket blocking again */ +{ + int i; + i = fcntl (s, F_GETFL, 0); +#ifdef VERBOSE + printf("FL on [%d] = %d\n", s, i); +#endif /* VERBOSE */ + i = i & (!O_NONBLOCK); /* mark it as non non-blocking, i.e. blocking */ + (void)fcntl (s, F_SETFL, i); +#ifdef VERBOSE + printf("New FL [%d] on [%d] returns [%d]\n", i, s, j); +#endif /* VERBOSE */ +} + +int setsendrecvbufs (int s,int bufsize ) /* Sets send/recv buffer sizes */ + /* returns 0 for ok and 1 for unix not accepting and -1 for error */ + /* if a problem occurs, it sets buffers back to what they were */ + /* Note: Bufsize is in kilobytes */ +{ + unsigned int sb_org, rb_org; + unsigned int sb_new, rb_new; + unsigned int sb_chk, rb_chk; + /* socklen_t */ int optsize; + int rc; + + optsize = sizeof (int); /* I hope... */ + + sb_new = bufsize * 1024; /* into bytes */ + rb_new = bufsize * 1024; /* into bytes */ + + if (sb_new<=0) { + fprintf(stderr, + "SNIPE_LITE:Conn:attempt to set send/recv bufs to %d ignored\n", + sb_new); + return (-1); + } + + /* get original values first */ + + rc = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&sb_org, &optsize); + rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rb_org, &optsize); + + /* Now to attempt to set the new ones */ + + rc = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&sb_new, optsize); + rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rb_new, optsize); + + /* Now to verify the socket options */ + + rc = getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&sb_chk, &optsize); + rc = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rb_chk, &optsize); + + /* ok junk debugging */ +#ifdef VERBOSE + printf("[sockopt] socket %d send org %d new %d vrfy %d\t\trecv org %d, new %d vrfy %d\n", + s, sb_org, sb_new, sb_chk, rb_org, rb_new, rb_chk); +#endif + + /* Now to do what we do */ + + /* if both are ok... worked */ + if ((sb_chk==sb_new)&&(rb_chk==rb_new)) return (0); + + /* if **either** match the older values */ + if ((sb_chk==sb_org)||(rb_chk==rb_org)) return (1); + + /* else we have to attempt a reset */ + rc = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&sb_org, optsize); + rc = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&rb_org, optsize); + + /* At this point we could check again, but there is little point as */ + /* if this hasn't changed it back we are in trouble anyway */ + return (1); +} + +double sec_time() +/* returns the time in seconds as a double */ +{ + struct timeval tp; + struct timezone tzp; + double sec=0.0; + double psec=0.0; + + gettimeofday (&tp, &tzp); + sec = (double)tp.tv_sec; + psec = ((double)tp.tv_usec)/1000000.0; + + return (sec+psec); +} + +/* Return: + * 0 if there is no loopback + * 1 if there is a loopback + * 2 if we found a legal IP adress (except loopback). + */ +int find_ip_on_all_interfaces( struct sockaddr_in *pAddr ) +{ + /******************************************************************/ +/* + * Get the interface device list, walk through it and deduce those + * interfaces which can broadcast. + */ + int i, sd, numdevs, have_loopback = 0; + struct ifconf ifc_conf; + char ifc_conf_buf[BUFSIZ]; /* 1024/32 == space for 32 interfaces */ + struct ifreq *devptr; + int ifc_conf_buf_size; + + /* + * Open a socket, any type will do so we choose UDP, and ask it with + * an ioctl call what devices are behind it. + */ + if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + /* HINT(LOG_CONN,"Error: Unable to create socket\n"); */ + goto complete_and_return; + } + + /* + * Fill the buffer with our static buffer, probably big enough, and get + * the interface configuration. + */ + ifc_conf_buf_size = sizeof ifc_conf_buf; + ifc_conf.ifc_len = ifc_conf_buf_size; + ifc_conf.ifc_buf = ifc_conf_buf; + if (ioctl(sd, SIOCGIFCONF, &ifc_conf) < 0) { + /* HINT(LOG_CONN,"Error: Unable to get network interface conf\n"); */ + close(sd); + goto complete_and_return; + } + if ((sizeof ifc_conf_buf - ifc_conf.ifc_len) <= sizeof(struct ifreq)) + /* HINT(LOG_CONN, "Info: More interfaces then we anticipated.\n"); */ + + /* + * Excess space should be larger than one ifreq or we need more. If + * the buffer was not big enough then we need to malloc a larger space + * and try again. There is no number of retries. We either get them + * all or we run out of memory. + */ + while ((sizeof(ifc_conf_buf) - ifc_conf.ifc_len) <= sizeof(struct ifreq)) { + if (ifc_conf_buf_size != sizeof(ifc_conf_buf)) + free(ifc_conf.ifc_buf); /* We allocated it last time around. */ + ifc_conf_buf_size *= 2; + ifc_conf.ifc_len = ifc_conf_buf_size; + if ((ifc_conf.ifc_buf = malloc(ifc_conf_buf_size)) == 0) { + /* HINT(LOG_CONN,"Error: Out of memory allocating interfaces.\n"); */ + close(sd); + goto complete_and_return; + } +#ifdef _AIX + if( ioctl(sd, CSIOCGIFCONF, &ifc_conf) < 0 ) +#else + if( ioctl(sd, SIOCGIFCONF, &ifc_conf) < 0) +#endif /* __aix__ */ + { + /* HINT(LOG_CONN,"Error: Unable to get network interface conf\n"); */ + close(sd); + goto complete_and_return; + } + } + + /* + * An array of devices were returned. Which ones are up right now and + * have broadcast capability? + */ + numdevs = ifc_conf.ifc_len / sizeof(struct ifreq); + for (i = 0; i < numdevs; i++) { + /* devptr points into an array of ifreq structs. */ + devptr = &ifc_conf.ifc_req[i]; + +#ifdef _AIX + if( (devptr->ifr_addr.sa_family != AF_INET) && (devptr->ifr_addr.sa_family != AF_INET6) && (devptr->ifr_addr.sa_family != AF_LINK) ) +#else + if( (devptr->ifr_addr.sa_family != AF_INET) ) +#endif + { + /* HINT(LOG_CONN, "not AF_INET device %s (%d)\n", devptr->ifr_name, devptr->ifr_addr.sa_family ); */ + continue; + } + + if (ioctl(sd, SIOCGIFFLAGS, devptr) < 0) { + /* HINT(LOG_CONN, "Error: Unable to get device interface flags.\n"); */ + goto complete_and_return; + } + + if ((devptr->ifr_flags & IFF_LOOPBACK) != 0) { + have_loopback = 1; + continue; + } + + if ((devptr->ifr_flags & IFF_UP) == 0) + continue; + + if ((devptr->ifr_flags & IFF_BROADCAST) == 0) + continue; + + *pAddr = *(struct sockaddr_in *) &(devptr->ifr_addr); + { + struct sockaddr_in x, *y; + y=(struct sockaddr_in *)&devptr->ifr_addr; + x=(*y); + } + + return 2; + } + + complete_and_return: + /* HINT(LOG_CONN, "nothing here %d devices \n", numdevs ); */ + close(sd); + return have_loopback; +} + +int get_ip_address(char *szHostName) +{ + struct in_addr loopback, out; + struct hostent *pHost; + int i; + + /* removed by the compiler if --enable-debug was not provided to the configure script */ + loopback.s_addr = htonl(INADDR_LOOPBACK); + if ((pHost = gethostbyname(szHostName)) != NULL) { + for (i = 0; pHost->h_addr_list[i] != NULL; i++) { + /* find the first one != local addresses (127.x.x.x) */ + memcpy(&(out.s_addr), pHost->h_addr_list[i], pHost->h_length); + if (out.s_addr != loopback.s_addr) { + return out.s_addr; + } + } + } + return 0; +} + +int get_my_addr( char** pdefault_name ) +{ + char szHostName[512]; + int rc; + struct sockaddr_in ip; + int len; + + if( default_name != NULL ) { + if( pdefault_name != NULL ) { + *pdefault_name = _MALLOC( strlen(default_name) + 1 ); + sprintf( *pdefault_name, "%s", default_name ); + } + return host_addr; + } + if( (pdefault_name != NULL) && ((*pdefault_name) != NULL) ) { + host_addr = get_ip_address( *pdefault_name ); + if( host_addr != 0 ) { + if( default_name != NULL ) _FREE( default_name ); + default_name = _MALLOC( strlen( *pdefault_name ) + 1 ); + sprintf( default_name, "%s", *pdefault_name ); + return host_addr; + } + } + if (gethostname(szHostName, 512) == 0) { + /* HINT(LOG_CONN,"hostname is %s\n",szHostName); */ + host_addr = get_ip_address(szHostName); + if(host_addr != 0) goto update_name; + + /* try FQDN */ + len = strlen(szHostName); + szHostName[len] = '.'; + if (getdomainname(szHostName + len + 1, 512 - len) != 0) { + /* HINT(LOG_CONN,"Unable to get the domain: %s\n",strerror(errno)); */ + goto complex_way; + } + /* HINT(LOG_CONN, "Complete host name is %s\n", szHostName ); */ + host_addr = get_ip_address(szHostName); + if( host_addr != 0) + goto update_name; + } + + complex_way: + /* Let's try the complex way */ + rc = find_ip_on_all_interfaces(&ip); + switch(rc) { + case 2: + sprintf( szHostName, "%s", inet_ntoa( ip.sin_addr ) ); + host_addr = ip.sin_addr.s_addr; + break; + case 1: + sprintf( szHostName, "%s", "127.0.0.1" ); /* hey why not !! */ + (void)inet_aton( "127.0.0.1", (struct in_addr*)&host_addr ); + break; + default: + return -1; + } + update_name: + if( pdefault_name != NULL ) { + if( (*pdefault_name) != NULL ) free( (*pdefault_name) ); + *pdefault_name = _MALLOC( strlen(szHostName) + 1 ); + sprintf( *pdefault_name, "%s", szHostName ); + } + default_name = _MALLOC( strlen(szHostName) + 1 ); + sprintf( default_name, "%s", szHostName ); + return host_addr; +} + +int free_default_name(void) +{ + if(default_name) _FREE(default_name); + return 0; +} + +/** + * getHostnameByAddr - getHostname from IP(v4) + * @param addr address + * @return hostname + * */ +char * getHostnameByAddr(int addr) +{ + struct hostent *hp; + struct in_addr saddr; + saddr.s_addr=addr; + hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET); + if (hp==NULL) { + return inet_ntoa(saddr); + } else { +#ifdef ENABLE_ALIASES /* Enable alias hostname */ + if(hp->h_aliases[0]!=NULL) { + return hp->h_aliases[0]; + } +#endif + if(hp->h_name !=NULL) { + return hp->h_name; + } else { + return inet_ntoa(saddr); + } + } +} diff --git a/src/mca/service/stdio/snipe_lite/snipe_lite.h b/src/mca/service/stdio/snipe_lite/snipe_lite.h new file mode 100644 index 0000000000..6c94e57160 --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/snipe_lite.h @@ -0,0 +1,110 @@ + + +/* + HARNESS G_HCORE + + Innovative Computer Laboratory, + University of Tennessee, + Knoxville, TN, USA. + + harness@cs.utk.edu + + -------------------------------------------------------------------------- + + Authors: Graham Fagg + + -------------------------------------------------------------------------- + + NOTICE + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose and without fee is hereby granted + provided that the above copyright notice appear in all copies and + that both the copyright notice and this permission notice appear in + supporting documentation. + + Neither the University of Tennessee nor the Authors make any + representations about the suitability of this software for any + purpose. This software is provided ``as is'' without express or + implied warranty. + + HARNESS, HARNESS G_HCORE and FT_MPI was funded in part by the + U.S. Department of Energy. + +*/ + + +/* + SNIPE_LITE was part of the SNIPE experimental metacomputing system + + the comms library was a non threaded 'get the message there' TCP + library that is a little more carefull than the cs340 socketfun stuff + + Incept for this code was in 1998. + +*/ + +#ifndef _SNIPE_LITE_H +#define _SNIPE_LITE_H 1 + +/* Syslog facility for snipe_lite */ +#include "syslog.h" +extern syslog_t* slsyslog; + +/* + Create listening socket etc +*/ + +int setportconn (int *s,int port,int range) ; +int allowconn (int s,int fe,int * spid); +int probeconn (int s,int fe,int * spid); +int pollconn (int s,int dir,int tout); + +/* + Client connect +*/ +int getconn (char * host,int * port,int search); /* by host name */ +int getconn_addr (unsigned long addr,int * port,int search); /* by sa_addr */ + +/* + Close by either side +*/ +int closeconn (int s); + +/* + Stream based blocking send/recv operations +*/ +int writeconn (int s,char * data,int len); +int readconn (int s,char * data,int len); + +/* + Message based/styled communications +*/ +int writemsgconn (int s,char * data,int len); +int readmsgconn (int s,char * data,int mlen); + + +void nodelay(int s); /* hack routine to improve performance.. maybe */ +void setnonblocking(int s); /* sets the given socket non-blocking */ +void setblocking(int s); /* sets the given socket blocking again */ +int setsendrecvbufs(int s, int bufsize); /* Sets send/recv buffer sizes */ +int free_default_name(void); + +char *getHostnameByAddr(int addr); + +/* Benchmarking ops */ +double sec_time(void); + +/* defines */ +/* these needs to be set per daemon type really */ + +#ifdef IMA_LINUX + #include + #define LISTENBACKLOG SOMAXCONN +#else + #define LISTENBACKLOG 128 +#endif + +int get_my_addr( char** pdefault_name ); + +#endif /* _SNIPE_LITE_H */ diff --git a/src/mca/service/stdio/snipe_lite/syslog.c b/src/mca/service/stdio/snipe_lite/syslog.c new file mode 100644 index 0000000000..6e83c76eb4 --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/syslog.c @@ -0,0 +1,196 @@ +#include "syslog.h" +#include "debug.h" +#include +#include + +typedef struct _log_flags { + char* name; + char* optname; + syslog_t** syslog; +} log_flag_t; + +struct syslog_t { + char* name; + int level; + FILE* output; + int private_id; +}; + +static log_flag_t logFlags[] = { + { "CONN", "conn", &LOG_CONN }, + { "RESTART", "restart", &LOG_RESTART }, + { "NOTIFIER", "not", &LOG_NOTIFIER }, + { "MPI", "mpi", &LOG_MPI }, + { "CALLBACK", "callback", &LOG_CALLBACK }, + { "DDT", "ddt", &LOG_DDT }, + { "IOVEC", "iovec", &LOG_IOVEC }, + { "SNIPE2", "snipe2", &LOG_SNIPE2 }, + { "SYS", "sys", &LOG_SYS } +}; + +syslog_t* conn_syslog = NULL; /* connection stuff */ +syslog_t* restart_syslog = NULL; /* restart messages */ +syslog_t* mpi_syslog = NULL; /* high level messages */ +syslog_t* notif_syslog = NULL; /* communications with the notifier */ +syslog_t* cb_syslog = NULL; /* callback functions */ +syslog_t* ddt_syslog = NULL; /* ddt stuff */ +syslog_t* iovec_syslog = NULL; /* iovec informations */ +syslog_t* snipe2_syslog = NULL; /* snipe2 information */ +syslog_t* sys_syslog = NULL; /* system messages */ + +int ftmpi_syslog_init( int private_id ) +{ + char envName[128]; + char *pEnv, *pFileEnv; + int i, pos = 0; + + pEnv = getenv( "HARNESS_FTMPI_DEBUG" ); + if( pEnv == NULL ) return 0; + + while( 1 ) { + if( pEnv[pos] == ' ' ) continue; + for( i = 0; i < (sizeof(logFlags) / sizeof(log_flag_t)); i++ ) { + if( strcmp( pEnv, logFlags[i].optname ) == 0 ) { + /* one of the flags is present */ + sprintf( envName, "HARNESS_FTMPI_%s_FILE", logFlags[i].name ); + pFileEnv = getenv( envName ); + if( pFileEnv == NULL ) + *(logFlags[i].syslog) = syslog_init( NULL, private_id, 100 ); + else { + FILE* pf = fopen( pFileEnv, "w" ); + if( pf == NULL ) { + fprintf( stderr, "Unable to open the file %s\n", pFileEnv ); + } else { + *(logFlags[i].syslog) = syslog_init( pf, private_id, 100 ); + } + } + pos += strlen(logFlags[i].optname); + break; + } + } + while( 1 ) { + if( pEnv[pos] == '\0' ) return 1; + if( pEnv[pos] == ',' ) pos++; + else if( pEnv[pos] == ' ' ) pos++; + else break; + } + } + return 1; +} + +syslog_t* syslog_init( FILE* output, int private_id, int level ) +{ + syslog_t* pSyslog = _MALLOC( sizeof(struct syslog_t) ); + + if( output == NULL ) pSyslog->output = stderr; + else pSyslog->output = output; + pSyslog->level = level; + pSyslog->private_id = private_id; +/* unsigned int activeFlags = LOG_RESTART|LOG_CONN|LOG_SYS|LOG_SNIPE2; */ + return pSyslog; +} + +int syslog_close( syslog_t** pSyslog ) +{ + if( (*pSyslog) == NULL ) return 0; + fflush( (*pSyslog)->output ); + _FREE( (*pSyslog) ); + *pSyslog = NULL; + return 0; +} + +void syslog_hint( syslog_t* pSyslog, const unsigned int level, const char* file, int lineno, const char* fmt, ... ) +{ + va_list list; + + if( pSyslog == NULL ) return; + if( level < pSyslog->level ) return; + + fprintf( pSyslog->output, "%x-%s:%d [H-%s] ", pSyslog->private_id, file, lineno, pSyslog->name ); + va_start( list, fmt ); + vfprintf( pSyslog->output, fmt, list ); + va_end( list ); +} + +void syslog_warning( syslog_t* pSyslog, const char* file, int lineno, const char* fmt, ... ) +{ + va_list list; + FILE* output; + int id = 0; + char* name = "UNKN"; + + if( pSyslog == NULL ) output = stderr; + else { + output = pSyslog->output; + id = pSyslog->private_id; + name = pSyslog->name; + } + + fprintf( output, "%x-%s:%d [W-%s] ", id, file, lineno, name ); + va_start( list, fmt ); + vfprintf( output, fmt, list ); + va_end( list ); +} + +void syslog_fatal( syslog_t* pSyslog, const char* file, int lineno, const char* fmt, ... ) +{ + va_list list; + FILE* output; + int id = 0; + char* name = "UNKN"; + + if( pSyslog == NULL ) output = stderr; + else { + output = pSyslog->output; + id = pSyslog->private_id; + name = pSyslog->name; + } + + fprintf( output, "%x-%s:%d [F-%s] ", id, file, lineno, name ); + va_start( list, fmt ); + vfprintf( output, fmt, list ); + va_end( list ); +#if !defined(NDEBUG) + { + int* l = NULL; + *l = 0; /* generate a SEGV could be trapped with a debugger */ + } +#endif /* NDEBUG */ +} + +#if !defined(NDEBUG) +# if !defined(__GNUC__) && !defined(ACCEPT_C99) +/* Simple case as the compiler thas not support macros with + * a variable number of arguments. + */ +void HINT( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... ) +{ + va_list list; + + va_start( list, fmt ); + syslog_hint( flags, "unknown", -1, fmt, list ); + va_end( list ); +} +# endif /* !defined(__GNUC__) && !defined(ACCEPT_C99) */ +#endif /* NDEBUG */ + +#if !defined(__GNUC__) && !defined(ACCEPT_C99) +void WARNING( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... ) +{ + va_list list; + + va_start( list, fmt ); + syslog_warning( flags, "unknown", -1, fmt, list ); + va_end( list ); +} + +void FATAL( syslog_t* psyslog, const unsigned int flags, const char* fmt, ... ) +{ + va_list list; + + va_start( list, fmt ); + syslog_fatal( flags, "unknown", -1, fmt, list ); + va_end( list ); +} +#endif /* !defined(__GNUC__) && !defined(ACCEPT_C99) */ + diff --git a/src/mca/service/stdio/snipe_lite/syslog.h b/src/mca/service/stdio/snipe_lite/syslog.h new file mode 100644 index 0000000000..c59abe6f1b --- /dev/null +++ b/src/mca/service/stdio/snipe_lite/syslog.h @@ -0,0 +1,118 @@ +#ifndef SYSLOG_H_HAS_BEEN_INCLUDED +#define SYSLOG_H_HAS_BEEN_INCLUDED + +#include "debug.h" + +typedef struct syslog_t syslog_t; + +#define LOG_CONN conn_syslog /* connection stuff */ +#define LOG_RESTART restart_syslog /* restart messages */ +#define LOG_MPI mpi_syslog /* high level messages */ +#define LOG_NOTIFIER notif_syslog /* communications with the notifier */ +#define LOG_CALLBACK cb_syslog /* callback functions */ +#define LOG_DDT ddt_syslog /* ddt stuff */ +#define LOG_IOVEC iovec_syslog /* iovec informations */ +#define LOG_SNIPE2 snipe2_syslog /* snipe2 information */ +#define LOG_SYS sys_syslog /* system messages */ + +extern syslog_t* conn_syslog; /* connection stuff */ +extern syslog_t* restart_syslog; /* restart messages */ +extern syslog_t* mpi_syslog; /* high level messages */ +extern syslog_t* notif_syslog; /* communications with the notifier */ +extern syslog_t* cb_syslog; /* callback functions */ +extern syslog_t* ddt_syslog; /* ddt stuff */ +extern syslog_t* iovec_syslog; /* iovec informations */ +extern syslog_t* snipe2_syslog; /* snipe2 information */ +extern syslog_t* sys_syslog; /* system messages */ + +extern syslog_t* syslog_init( FILE* output, int private_id, int level ); +extern void syslog_hint( syslog_t* syslog, const unsigned int level, + const char* file, int lineno, + const char* fmt, ... ); +extern void syslog_warning( syslog_t* syslog, + const char* file, int lineno, + const char* fmt, ... ); +extern void syslog_fatal( syslog_t* syslog, + const char* file, int lineno, + const char* fmt, ... ); + +#if defined(NDEBUG) +# if defined(__GNUC__) +# define DO_DEBUG(args...) +# define HINT( SYSLOG, LEVEL, FMT...) +# define WARNING( SYSLOG, FMT... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, ##FMT ) +# define FATAL( SYSLOG, FMT... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, ##FMT ) +# else +# if defined(ACCEPT_C99) +# define DO_DEBUG( ... ) +# define HINT( SYSLOG, LEVEL, args... ) +# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ ) +# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ ) +# else +# define DO_DEBUG( Args ) + static void HINT( syslog_t* syslog, const unsigned int level, const char* fmt, ... ) { /* empty hopefully removed by the compiler */}; + extern void WARNING( syslog_t* syslog, const char* fmt, ... ); + extern void FATAL( syslog_t* syslog, const char* fmt, ... ); +# endif /* ACCEPT_C99 */ +# endif /* __GNUC__ */ +#else /* NDEBUG not defined */ +# if defined(__GNUC__) +# define DO_DEBUG(args...) args +# define HINT( SYSLOG, LEVEL, FMT, args...) if( (SYSLOG) != NULL ) syslog_hint( (SYSLOG), (LEVEL), __FILE__, (int)__LINE__, FMT, ##args ) +# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), ##args ) +# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), ##args ) +# else +# if defined(ACCEPT_C99) +# define DO_DEBUG( ... ) __VA_ARGS__ +# define HINT( SYSLOG, LEVEL, args... ) if( (SYSLOG) != NULL ) syslog_hint( (SYSLOG), (LEVEL), __FILE__, (int)__LINE__, __VA_ARGS__ ) +# define WARNING( SYSLOG, FMT, args... ) syslog_warning( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ ) +# define FATAL( SYSLOG, FMT, args... ) syslog_fatal( (SYSLOG), __FILE__, __LINE__, (FMT), __VA_ARGS__ ) +# else +# define DO_DEBUG( Args ) Args + extern void HINT( syslog_t* syslog, const unsigned int level, const char* fmt, ... ); + extern void WARNING( syslog_t* syslog, const char* fmt, ... ); + extern void FATAL( syslog_t* syslog, const char* fmt, ... ); +# endif /* ACCEPT_C99 */ +# endif /* __GNUC__ */ +#endif /* NDEBUG */ + +#include +#include +#include +#include +#include +#include +extern int errno; +#define DUMP_SOCKET_ERROR(SOCK, ERRNO) \ +do { \ + struct sockaddr_in sockname; \ + socklen_t length = sizeof(struct sockaddr); \ + \ + if( getpeername( (SOCK), (struct sockaddr*)&sockname, &length ) == 0 ) { \ + WARNING( LOG_CONN, "sock %d [%s:%d] generate error %d %s\n", \ + (SOCK), inet_ntoa(sockname.sin_addr), sockname.sin_port, \ + (ERRNO), strerror((ERRNO)) ); \ + } else { \ + WARNING( LOG_CONN, "unable to get the peer name on socket %d. error %d %s\n", \ + (SOCK), errno, strerror(errno) ); \ + if( (ERRNO) != 0 ) \ + WARNING( LOG_CONN, " initial error was %d:%s\n", (ERRNO), strerror((ERRNO)) ); \ + } \ +} while (0) + +#define DUMP_SOCKET_INFO(LOGGING, SOCK, SSTR, ESTR) \ +do { \ + struct sockaddr_in sockname; \ + socklen_t length = sizeof(struct sockaddr); \ + \ + if( getpeername( (SOCK), (struct sockaddr*)&sockname, &length ) == 0 ) { \ + HINT( LOGGING, 10, " %s sock %d [%s:%d] %s", (SSTR), \ + (SOCK), inet_ntoa(sockname.sin_addr), sockname.sin_port, (ESTR) ); \ + } else { \ + HINT( LOGGING, 10, " unable to get the peer name on socket %d. error %d %s\n", \ + (SOCK), errno, strerror(errno) ); \ + HINT( LOGGING, 10, " %s sock %d [??:??] %s", (SSTR), (SOCK), (ESTR) ); \ + } \ +} while (0) + +#endif /* SYSLOG_H_HAS_BEEN_INCLUDED */