vxwserv.c
Go to the documentation of this file.
00001 /* vxwserv.c
00002 /* spawned from server
00003 /* This program is supposed to run on any vxworks machines, not Lisp.
00004 */
00005 
00006 #include "vxWorks.h"
00007 #include "stdioLib.h"
00008 #include "socket.h"
00009 #include "in.h"
00010 #include "sigLib.h"
00011 #include "taskLib.h"
00012 
00013 #include "vxw_proto.h"
00014 
00015 #define SERVER_NUM 2200
00016 #define ARGUMENT_BUFFER_SIZE 16384
00017 
00018 extern char *sysSymTbl;
00019 
00020 static int error_code;
00021 
00022 /****************************************************************/
00023 
00024 void protocol_error(x)
00025 int x;
00026 { printf("VxWs protocol error %d\n",x);
00027   error_code=x; }
00028 
00029 static getint(type, s)
00030 enum argument_type type;
00031 register FILE *s;
00032 { register int ival=0;
00033   switch(type) {
00034   A_LONG:  ival=(getc(s)<<24)+(getc(s)<<16);
00035   A_SHORT: ival+=(getc(s)<<8);
00036   A_CHAR:  return(ival+getc(s));}
00037   }
00038 
00039 static double getfloat(type, s)
00040 enum argument_type type;
00041 register FILE *s;
00042 { double dval=0.0;
00043   number_union nu;
00044   switch(type) {
00045   case A_FLOAT: nu.i.ival1=getw(s); return(nu.f.fval1);
00046   case A_DOUBLE: nu.i.ival1=getw(s); nu.i.ival2=getw(s); return(nu.dval);
00047   }}
00048 
00049 static getlength(s)
00050 FILE *s;
00051 { int len;
00052   len=getc(s);
00053   if (len & 0x80) {
00054     if (len & 0x40) /*32bit length*/
00055       return(((len & 0x3f)<<24) + (getc(s)<<16) + (getc(s)<<8) + getc(s));
00056     else return(((len & 0x7f)<<8) + getc(s)); }
00057   else return(len);}
00058 
00059 static int getvector(s,vmem,index,bufsize)
00060 register FILE *s;
00061 register unsigned char *vmem;
00062 register int index;
00063 int bufsize;
00064 { register int i,length;
00065   length=getlength(s);
00066   if (index+length >= bufsize-100) {
00067     protocol_error(3);  /* vector buffer overflow*/
00068     for (i=0; i<length; i++) getc(s);   /*skip vector elements*/
00069     return(index);}
00070   for (i=0; i<length; i++) vmem[index++]=getc(s);
00071   i=4-(length % 4);
00072   while (i-- >0) vmem[index++] =0;      /*align to long word boundary */
00073   return(index);}
00074 
00075 int findsymbol(s)
00076 char *s;
00077 { int stat, entry, entry_type;
00078   if (symFindByName(sysSymTbl, s, &entry, &entry_type) == OK) return(entry);
00079   else return(ERROR);}
00080 
00081 static int getsymbol(s)
00082 register FILE *s;
00083 { char symstr[256];
00084   register int i,len;
00085   int stat, entry, entry_type;
00086   
00087   len=getlength(s);
00088   for (i=0; i<len; i++) symstr[i+1]=getc(s);
00089   symstr[len+1]=0;
00090   stat=symFindByName(sysSymTbl, &symstr[1], &entry, &entry_type);
00091   if (stat==ERROR) {
00092     symstr[0]='_';
00093     stat=symFindByName(sysSymTbl, symstr, &entry, &entry_type);
00094     if (stat==ERROR) return(ERROR);}
00095   return(entry);}
00096 
00097 int call_vxw(fd)
00098 int fd;
00099 { FILE *s, *ws;
00100   int bufsize, running=1, callee, tid, result_type;
00101   int nextfree, i, j, len;      /*argument counter*/
00102   int (*ifunc)();
00103   double (*ffunc)();
00104   double f;
00105   enum argument_type type;
00106   long cargv[32];
00107   number_union nu;
00108   unsigned char *ip, *vmem;
00109 
00110   if ((s=fdopen(fd,"r"))==NULL) { printf("cannot fdopen read\n"); exit(2);}
00111   if ((ws=fdopen(fd,"w"))==NULL) { printf("cannot fdopen write\n"); exit(2);}
00112 
00113   tid=taskIdSelf();
00114   taskVarAdd(tid, &error_code);
00115   bufsize=getw(s);
00116   vmem = malloc(bufsize);
00117   if (malloc==NULL) { protocol_error(7); return(7);}
00118 
00119   printf("VxWserv v1.0 started with %d byte buffer\n", bufsize);
00120 
00121   while (running) {
00122     nextfree=i=j=0; error_code=0;
00123     type=getc(s);
00124     if (type==EOF) { protocol_error(5); break;}
00125     if (type==A_SYMBOL) { 
00126       callee=getsymbol(s);
00127       if (callee==ERROR) protocol_error(1); }
00128     else if (type==A_LONG) callee=getw(s);
00129     else protocol_error(2);
00130 
00131 /*    printf("entry=0x%x\n", callee); */
00132 
00133     type=getc(s);
00134     while (type!=A_END) { 
00135       if (j>=32) protocol_error(5);
00136       switch(type) {
00137         case A_CHAR:  cargv[i++]=getc(s); break;
00138         case A_SHORT: cargv[i++]=(getc(s)<<8) + getc(s); break;
00139         case A_LONG:  cargv[i++]=getw(s); break;
00140         case A_FLOAT: len=getw(s); nu.i.ival1=len;
00141                         nu.dval=nu.f.fval1;
00142                       cargv[i++]=nu.i.ival1; cargv[i++]=nu.i.ival2;
00143                       break;
00144         case A_SYMBOL: cargv[i++]=getsymbol(s); break;
00145         case A_VECTOR: cargv[i++]= &vmem[nextfree];
00146                        nextfree=getvector(s,vmem,nextfree,bufsize);
00147                        break;
00148         default: protocol_error(4); break; }
00149       j++;
00150       type=getc(s); /*next arg type*/
00151       if (type==EOF) protocol_error(6);
00152       } /*end of reading arguments*/
00153 
00154     result_type=getc(s);
00155 
00156     /* protocol analysis finished, return the status*/
00157     putc(error_code, ws);
00158     if (error_code==5) break;   /*communication broke down*/
00159 
00160     if (error_code!=0) { /*error occurred, abort invokation*/ }
00161     else if (result_type==A_FLOAT || result_type==A_DOUBLE) {
00162       ffunc=callee;
00163       if (j<=8) 
00164         f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00165                    cargv[4],cargv[5],cargv[6],cargv[7]);
00166         else if (j<=32)
00167         f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00168                    cargv[4],cargv[5],cargv[6],cargv[7],
00169                    cargv[8],cargv[9],cargv[10],cargv[11],
00170                    cargv[12],cargv[13],cargv[14],cargv[15],
00171                    cargv[16],cargv[17],cargv[18],cargv[19],
00172                    cargv[20],cargv[21],cargv[22],cargv[23],
00173                    cargv[24],cargv[25],cargv[26],cargv[27],
00174                    cargv[28],cargv[29],cargv[30],cargv[31]);
00175 /*      printf("result=%lf\n",f); */
00176       nu.f.fval1=f;     /*coerce double to float*/
00177       putw(nu.i.ival1, ws);}
00178     else {
00179       ifunc=callee;
00180       if (j<8) 
00181         i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00182                    cargv[4],cargv[5],cargv[6],cargv[7]);
00183       else if (j<=32)
00184         i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00185                    cargv[4],cargv[5],cargv[6],cargv[7],
00186                    cargv[8],cargv[9],cargv[10],cargv[11],
00187                    cargv[12],cargv[13],cargv[14],cargv[15],
00188                    cargv[16],cargv[17],cargv[18],cargv[19],
00189                    cargv[20],cargv[21],cargv[22],cargv[23],
00190                    cargv[24],cargv[25],cargv[26],cargv[27],
00191                    cargv[28],cargv[29],cargv[30],cargv[31]);
00192 /*      printf("result=%d\n",i); */
00193       if (result_type==A_CHAR || result_type==A_SHORT || result_type==A_LONG)
00194         putw(i,ws);
00195       else if (result_type==A_VECTOR) {
00196         len=getlength(s); ip=(unsigned char *) i;
00197         for (j=0; j<len; j++) { putc(*ip, ws); ip++;} 
00198         }
00199       }
00200     fflush(ws);}  /*running*/
00201 
00202   fclose(s);  free(vmem);
00203   printf("connection closed\n"); }
00204 
00205 /* spawn a new server */
00206 
00207 
00208 static int sock;        /* socket fd's */
00209 
00210 int spawn_vxw(fd)
00211 int fd;
00212 { char taskname[16];
00213   int stat,entry,entry_type;
00214   static int task_id=1;
00215   unsigned char option,priority;
00216 
00217   read(fd, &priority,1);
00218   read(fd, &option, 1); 
00219   sprintf(taskname,"VxWs_%d",task_id++);
00220   stat=taskSpawn(taskname, priority, option, 3000,call_vxw,fd);
00221   if (stat==ERROR) {  printf("cannot spawn\n"); return(ERROR); }
00222   else return(OK);}
00223 
00224 static void abort(sig)
00225 int sig;
00226 { printf("vxwserv aborting\n");
00227   close(sock);
00228   exit(sig);}
00229 
00230 vxwserv ()
00231  {  int snew;
00232     struct sockaddr_in  serverAddr;     /* server's address */
00233     struct sockaddr_in  clientAddr;     /* client's address */
00234     int                 client_len;     /* length of clientAddr */
00235     int                 connection_count=0;
00236     unsigned char special;
00237     SIGVEC      sigabort;
00238 
00239     sigabort.sv_handler = abort;
00240     sigabort.sv_mask = !SIGMASK(SIGINT);
00241     sigabort.sv_flags= 0;
00242     sigvec(SIGINT, &sigabort, 0);
00243 
00244     /* Zero out the sock_addr structures.
00245      * This MUST be done before the socket calls.     */
00246 
00247     bzero (&serverAddr, sizeof (serverAddr));
00248     bzero (&clientAddr, sizeof (clientAddr));
00249 
00250     sock = socket (AF_INET, SOCK_STREAM, 0);
00251     if (sock == ERROR) exit (1);
00252     else printf("listening on socket %d\n",sock);
00253     /* Set up our internet address, and bind it so the client can connect. */
00254 
00255     serverAddr.sin_family = AF_INET;
00256     serverAddr.sin_port   = SERVER_NUM;
00257 
00258     while (bind (sock, (SOCKADDR *)&serverAddr, sizeof(serverAddr))==ERROR) {
00259         printf ("bind failed, errno = %d\n", errnoGet());
00260         serverAddr.sin_port++; }
00261     printf ("port %d is bound.\n", serverAddr.sin_port);
00262     /* Listen, for the client to connect to us. */
00263     if (listen (sock, 2) == ERROR) {
00264         printf ("listen failed\n");
00265         close (sock);
00266         exit (1);}
00267 
00268     /* accept-fork loop */
00269     while (1) {
00270       client_len = sizeof (clientAddr);
00271       snew = accept (sock, (SOCKADDR *)&clientAddr, &client_len);
00272       if (snew==ERROR) { printf("accept failed\n"); close(sock); break;}
00273       printf("CLIENT accepted: sock=%d port=%d  family=%d  addr=%lx\n", 
00274             snew,
00275             clientAddr.sin_port, clientAddr.sin_family, 
00276             clientAddr.sin_addr.s_addr);
00277       connection_count++ ;
00278       read(snew, &special, 1);  /*ignore first byte*/
00279       if (spawn_vxw(snew)==ERROR)
00280          { printf("spawn failed\n"); } ;
00281       }
00282     printf ("totally %d connections established\n",connection_count);
00283     close (sock); }


euslisp
Author(s): Toshihiro Matsui
autogenerated on Thu Sep 3 2015 10:36:20