Annotation of OpenXM/src/kan96xx/plugin/sm1Socket.c, Revision 1.1
1.1 ! maekawa 1: /* msg0s.c */
! 2: #include <stdio.h>
! 3: #include <sys/types.h>
! 4: #include <sys/socket.h>
! 5: #include <sys/time.h>
! 6: #include <netinet/in.h>
! 7: #include <netdb.h>
! 8:
! 9:
! 10: #include "datatype.h"
! 11: #include "stackm.h"
! 12: #include "extern.h"
! 13: #include "sm1Socket.h"
! 14:
! 15: extern int Quiet;
! 16: static void errorMsg1s(char *s);
! 17:
! 18: /* [(sm1.socket) (open) [optional integer port, optional string name] ] extension ; */
! 19: struct object KsocketOpen(struct object obj) {
! 20: char serverName[1024];
! 21: int portNumber;
! 22: struct object rob = NullObject;
! 23: struct hostent *myhost;
! 24: struct sockaddr_in me;
! 25: int s_waiting;
! 26: int on;
! 27: int tt;
! 28: extern int errno;
! 29:
! 30: if (obj.tag != Sarray) {
! 31: errorMsg1s("KsocketOpen([optional integer,optional string name])");
! 32: }
! 33: strcpy(serverName,"localhost");
! 34: portNumber = 0;
! 35: if (getoaSize(obj) >= 1) {
! 36: if ((getoa(obj,0)).tag != Sinteger) {
! 37: errorMsg1s("KsocketOpen([optional integer,optional string name]), the first argument must be an integer.");
! 38: }
! 39: portNumber = KopInteger(getoa(obj,0));
! 40: }
! 41: if (getoaSize(obj) >= 2) {
! 42: if ((getoa(obj,1)).tag != Sdollar) {
! 43: errorMsg1s("KsocketOpen([optional integer,optional string name]), the second argument must be a string.");
! 44: }
! 45: if (strlen(KopString(getoa(obj,1))) > 1023) {
! 46: errorMsg1s("Too long server name");
! 47: }
! 48: strcpy(serverName,KopString(getoa(obj,1)));
! 49: }
! 50:
! 51:
! 52: /* fprintf(stderr,"Hello from open.\n"); */
! 53: if ((myhost = gethostbyname(serverName)) == NULL) {
! 54: errorMsg1s("Bad server name.");
! 55: }
! 56: bzero((char *)&me,sizeof(me));
! 57: me.sin_family = AF_INET;
! 58: me.sin_port = htons(portNumber);
! 59: bcopy(myhost->h_addr,
! 60: &me.sin_addr,myhost->h_length);
! 61:
! 62: if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) {
! 63: errorMsg1s("Socket allocation is failed.");
! 64: }
! 65:
! 66: on=1; setsockopt(s_waiting,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
! 67: /* important */
! 68: if (bind(s_waiting,(struct sockaddr *) &me,sizeof(me)) == -1) {
! 69: fprintf(stderr,"Bind error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 70: errorMsg1s("cannot bind");
! 71: }
! 72:
! 73: tt = sizeof(me);
! 74: if (getsockname(s_waiting,(struct sockaddr *)&me,&tt) < 0) {
! 75: fprintf(stderr,"getsockname error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 76: errorMsg1s("cannot getsockname");
! 77: }
! 78:
! 79:
! 80: if (listen(s_waiting,1) < 0) {
! 81: errorMsg1s("Listen failed");
! 82: }
! 83: /*
! 84: fprintf(stderr,"Done the initialization. port =%d\n",ntohs(me.sin_port));
! 85: fprintf(stderr,"socket id = %d",accept(s_waiting,NULL,NULL)); */
! 86: rob = newObjectArray(2);
! 87: putoa(rob,0,KpoInteger(s_waiting));
! 88: putoa(rob,1,KpoInteger(ntohs(me.sin_port)));
! 89: return(rob);
! 90:
! 91: }
! 92:
! 93: /* [ integer port, optional string host default localhost]
! 94: [ integer socketid, integer port ] */
! 95: struct object KsocketConnect(struct object obj) {
! 96: char serverName[1024];
! 97: int portNumber;
! 98: struct hostent *servhost;
! 99: struct sockaddr_in server;
! 100: int socketid;
! 101: struct object robj = NullObject;
! 102:
! 103: if (obj.tag != Sarray) {
! 104: errorMsg1s("KsocketConnect( [ integer port, optional string host default localhost])");
! 105: }
! 106: strcpy(serverName,"localhost");
! 107: if (getoaSize(obj) < 1) {
! 108: errorMsg1s("You need to specify port number.\n");
! 109: }
! 110: if (getoaSize(obj) >= 1) {
! 111: if ((getoa(obj,0)).tag != Sinteger) {
! 112: errorMsg1s("KsocketConnect([integer port,optional string host]), the first argument must be an integer.");
! 113: }
! 114: portNumber = KopInteger(getoa(obj,0));
! 115: }
! 116: if (getoaSize(obj) >= 2) {
! 117: if ((getoa(obj,1)).tag != Sdollar) {
! 118: errorMsg1s("KsocketConnect([integer port,optional string host]), the second argument must be a string.");
! 119: }
! 120: if (strlen(KopString(getoa(obj,1))) > 1023) {
! 121: errorMsg1s("Too long server name");
! 122: }
! 123: strcpy(serverName,KopString(getoa(obj,1)));
! 124: }
! 125:
! 126:
! 127: if ((servhost = gethostbyname(serverName)) == NULL) {
! 128: errorMsg1s("bad server name.\n");
! 129: }
! 130: bzero((char *)&server,sizeof(server));
! 131: server.sin_family = AF_INET;
! 132: server.sin_port = htons(portNumber);
! 133: bcopy(servhost->h_addr,
! 134: (char *)&server.sin_addr,servhost->h_length);
! 135:
! 136: if ((socketid = socket(AF_INET,SOCK_STREAM,0)) <0) {
! 137: errorMsg1s("socket allocation is failed.\n");
! 138: }
! 139: if (!Quiet) {
! 140: fprintf(stderr,"Trying to connect port %d, ip=%x\n",ntohs(server.sin_port),server.sin_addr);
! 141: }
! 142: if (connect(socketid,(struct sockaddr *)&server,sizeof(server)) == -1) {
! 143: errorMsg1s("cannot connect");
! 144: }
! 145: /* fprintf(stderr,"connected.\n"); */
! 146: robj = newObjectArray(2);
! 147: putoa(robj,0,KpoInteger(socketid));
! 148: putoa(robj,1,KpoInteger(portNumber));
! 149: return(robj);
! 150: }
! 151:
! 152: /* [ integer socketid ]
! 153: [ integer newsocketid ] */
! 154: struct object KsocketAccept(struct object obj) {
! 155: struct object obj1;
! 156: struct object obj2;
! 157: struct object robj;
! 158: int s, news;
! 159:
! 160: if (obj.tag != Sarray) {
! 161: errorMsg1s("KsocketAccept([integer socketid])");
! 162: }
! 163: if (getoaSize(obj) < 1) {
! 164: errorMsg1s("KsocketAccept([integer socketid])");
! 165: }
! 166: obj1 = getoa(obj,0);
! 167: if (obj1.tag != Sinteger ) {
! 168: errorMsg1s("KsocketAccept([integer socketid]), argument must be integer.");
! 169: }
! 170: s = KopInteger(obj1);
! 171: if ((news = accept(s,NULL,NULL)) < 0) {
! 172: errorMsg1s("Error in accept.");
! 173: }
! 174: if (close(s) < 0) {
! 175: errorMsg1s("Error in closing the old socket.");
! 176: }
! 177: robj = newObjectArray(1);
! 178: putoa(robj,0,KpoInteger(news));
! 179: return(robj);
! 180: }
! 181:
! 182: int KsocketSelect0(int fd,int t) {
! 183: fd_set readfds;
! 184: struct timeval timeout;
! 185: extern int errno;
! 186: FD_ZERO(&readfds);
! 187: FD_SET(fd,&readfds);
! 188: timeout.tv_sec = 0;
! 189: timeout.tv_usec = (long) t;
! 190: if (t >= 0) {
! 191: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
! 192: /* It must be fd+1 !, Not fd. */
! 193: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 194: errorMsg1s("KsocketSelect0() : select failed.");
! 195: return(0);
! 196: }
! 197: }else{ /* block */
! 198: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
! 199: errorMsg1s("KsocketSelect0() : select failed.");
! 200: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 201: return(0);
! 202: }
! 203: }
! 204: if (FD_ISSET(fd,&readfds)) return(1);
! 205: else return(0);
! 206: }
! 207:
! 208: /* [ integer socketid optional integer timeout default 0]
! 209: integer true or false
! 210: */
! 211: struct object KsocketSelect(struct object obj) {
! 212: struct object robj;
! 213: struct object ob1;
! 214: struct object ob2;
! 215: if (obj.tag != Sarray) {
! 216: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
! 217: }
! 218: if (getoaSize(obj) < 1) {
! 219: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0]");
! 220: }
! 221: if (getoaSize(obj) >= 1) {
! 222: ob1 = getoa(obj,0);
! 223: ob2 = KpoInteger(0); /* default value */
! 224: }
! 225: if (getoaSize(obj) >= 2) {
! 226: ob2 = getoa(obj,1);
! 227: }
! 228: if (ob1.tag != Sinteger) {
! 229: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the first argument must be an integer.");
! 230: }
! 231: if (ob2.tag != Sinteger) {
! 232: errorMsg1s("KsocketSelect([ integer socketid optional integer timeout default 0] : the second argument must be an integer.");
! 233: }
! 234: robj = KpoInteger( KsocketSelect0(KopInteger(ob1),KopInteger(ob2)) );
! 235: return(robj);
! 236: }
! 237:
! 238: struct object KsocketSelectMulti(struct object obj)
! 239: /* [ [integer socketid1, integer socketid2, ...]
! 240: optional integer timeout default 0]
! 241: [ result1, result2, ....]
! 242: */
! 243: {
! 244: struct object robj;
! 245: struct object ob1;
! 246: struct object ob2;
! 247: struct object ob3;
! 248: int size,i,fd,p,t;
! 249: fd_set readfds;
! 250: struct timeval timeout;
! 251: extern errno;
! 252: if (obj.tag != Sarray) {
! 253: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
! 254: }
! 255: if (getoaSize(obj) < 1) {
! 256: errorMsg1s("KsocketSelectMulti([[sid1, sid2,...] optional integer timeout default 0]");
! 257: }
! 258: if (getoaSize(obj) >= 1) {
! 259: ob1 = getoa(obj,0);
! 260: ob2 = KpoInteger(0); /* default value */
! 261: }
! 262: if (getoaSize(obj) >= 2) {
! 263: ob2 = getoa(obj,1);
! 264: }
! 265: if (ob1.tag != Sarray) {
! 266: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the first argument must be an array.");
! 267: }
! 268: if (ob2.tag != Sinteger) {
! 269: errorMsg1s("KsocketSelectMulti([[sid1, sid2, ...] optional integer timeout default 0] : the second argument must be an integer.");
! 270: }
! 271: FD_ZERO(&readfds);
! 272: timeout.tv_sec = 0; t = KopInteger(ob2);
! 273: timeout.tv_usec = (long)t;
! 274:
! 275: size = getoaSize(ob1);
! 276: if (size < 1) {
! 277: errorMsg1s("KsocketSelectMulti: the first argument must be a non-empty array of integers.");
! 278: }
! 279: fd = 0;
! 280:
! 281: for (i=0; i<size; i++) {
! 282: ob3 = getoa(ob1,i);
! 283: if (ob3.tag != Sinteger) {
! 284: errorMsg1s("KsocketSelectMulti: the first argument must be an array of integers.");
! 285: }
! 286: p = KopInteger(ob3);
! 287: if (p > fd) fd = p;
! 288: FD_SET(p,&readfds);
! 289: /* printf("p = %d, fd=%d",p,fd); */
! 290: }
! 291:
! 292: if (t >= 0) {
! 293: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) {
! 294: /* It must be fd+1 !, Not fd. */
! 295: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 296: errorMsg1s("KsocketSelectMulti() : select failed.");
! 297: }
! 298: }else{ /* block */
! 299: if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) {
! 300: fprintf(stderr,"Select error. Error no is %d. See /usr/include/sys/errno.h.\n",errno);
! 301: errorMsg1s("KsocketSelectMulti() : (block) select failed.");
! 302: }
! 303: }
! 304: robj = newObjectArray(size);
! 305: for (i=0; i<size; i++) {
! 306: if (FD_ISSET(KopInteger(getoa(ob1,i)),&readfds)) {
! 307: putoa(robj,i,KpoInteger(1));
! 308: }else{
! 309: putoa(robj,i,KpoInteger(0));
! 310: }
! 311: }
! 312:
! 313: return(robj);
! 314: }
! 315:
! 316:
! 317:
! 318:
! 319: static char Data00[1024];
! 320: /* [ integer socketid ]
! 321: string data
! 322: */
! 323: struct object KsocketRead(struct object obj) {
! 324: struct object ob1;
! 325: struct object robj = NullObject;
! 326: static int datasize = 1024;
! 327: static char *data = Data00;
! 328: char *tmp;
! 329: char *r;
! 330: int n;
! 331: int socketid;
! 332: int totalsize;
! 333:
! 334: if (obj.tag != Sarray) {
! 335: errorMsg1s("KsocketRead([integer socketid])");
! 336: }
! 337: if (getoaSize(obj) < 1) {
! 338: errorMsg1s("KsocketRead([integer socketid])");
! 339: }
! 340: ob1 = getoa(obj,0);
! 341: if (ob1.tag != Sinteger) {
! 342: errorMsg1s("KsocketRead([integer socketid]) : the argument must be integer.");
! 343: }
! 344: socketid = KopInteger(ob1);
! 345:
! 346: totalsize = 0;
! 347:
! 348: while (KsocketSelect0(socketid,0)) {
! 349: if (datasize - totalsize > 0) {
! 350: n = read(socketid,data+totalsize,datasize-totalsize);
! 351: if (n < 0) {
! 352: errorMsg1s("Read error.");
! 353: }
! 354: if (n < datasize-totalsize) {
! 355: totalsize += n;
! 356: break;
! 357: }else{ totalsize += n; }
! 358: if (totalsize == 0) {
! 359: errorMsg1s("Select returns 1, but there is no data to read.");
! 360: }
! 361: }else { /* increase the datasize */
! 362: tmp = (char *)GC_malloc(sizeof(char)*2*datasize);
! 363: /*I should use GC_malloc_atomic and free after finishing this function?*/
! 364: if (tmp == (char *)NULL) errorMsg1s("Out of Memory.");
! 365: bcopy(data,tmp,totalsize);
! 366: data = tmp;
! 367: datasize = 2*datasize;
! 368: }
! 369: }
! 370:
! 371: r = (char *)GC_malloc(sizeof(char)*(n+1));
! 372: if (r == (char *)NULL) errorMsg1s("Out of Memory.");
! 373: bcopy(data,r,totalsize);
! 374: robj = KpoString(r);
! 375:
! 376: return(robj);
! 377:
! 378: }
! 379:
! 380: /* [ integer socketid, string data ]
! 381: integer */
! 382: struct object KsocketWrite(struct object obj) {
! 383: struct object ob1;
! 384: struct object ob2;
! 385: int socketid;
! 386: int r;
! 387: if (obj.tag != Sarray) {
! 388: errorMsg1s("KsocketWrite([integer socketid, string data])");
! 389: }
! 390: if (getoaSize(obj) < 2) {
! 391: errorMsg1s("KsocketWrite([integer socketid, string data])");
! 392: }
! 393: ob1 = getoa(obj,0);
! 394: ob2 = getoa(obj,1);
! 395: if (ob1.tag != Sinteger) {
! 396: errorMsg1s("KsocketWrite([integer socketid, string data]) : the first argument must be an integer.");
! 397: }
! 398: socketid = KopInteger(ob1);
! 399: if (ob2.tag != Sdollar) {
! 400: errorMsg1s("KsocketWrite([integer socketid, string data]) : the second argument must be a string.");
! 401: }
! 402: r = write(socketid,KopString(ob2), strlen(KopString(ob2)));
! 403: return(KpoInteger(r));
! 404:
! 405: }
! 406: struct object KsocketClose(struct object obj) {
! 407: int socketid;
! 408: struct object ob1;
! 409: if (obj.tag != Sarray) {
! 410: errorMsg1s("KsocketClose([ integer socketid ])");
! 411: }
! 412: if (getoaSize(obj) != 1) {
! 413: errorMsg1s("KsocketClose([ integer socketid ])");
! 414: }
! 415: ob1 = getoa(obj,0);
! 416: if (ob1.tag != Sinteger) {
! 417: errorMsg1s("KsocketClose([ INTEGER socketid ])");
! 418: }
! 419: socketid = KopInteger(ob1);
! 420: return(KpoInteger(close(socketid)));
! 421: }
! 422:
! 423:
! 424: static void errorMsg1s(char *s) {
! 425: fprintf(stderr,"%s\n",s);
! 426: errorKan1("msg1s.c: %s\n",s);
! 427: }
! 428:
! 429:
! 430: /**************** new 1997, 11/23 *******************/
! 431: struct object KsocketReadByte(struct object obj);
! 432: struct object KsocketWriteByte(struct object obj);
! 433:
! 434: struct object KsocketReadByte(struct object obj) {
! 435: struct object ob1;
! 436: struct object robj = NullObject;
! 437: char data[2];
! 438: char *tmp;
! 439: char *r;
! 440: int n;
! 441: int socketid;
! 442:
! 443:
! 444: if (obj.tag != Sarray) {
! 445: errorMsg1s("KsocketReadByte([integer socketid])");
! 446: }
! 447: if (getoaSize(obj) < 1) {
! 448: errorMsg1s("KsocketReadByte([integer socketid])");
! 449: }
! 450: ob1 = getoa(obj,0);
! 451: if (ob1.tag != Sinteger) {
! 452: errorMsg1s("KsocketReadByte([integer socketid]) : the argument must be integer.");
! 453: }
! 454: socketid = KopInteger(ob1);
! 455:
! 456:
! 457: n = read(socketid,data,1);
! 458: if (n < 0) {
! 459: errorMsg1s("Read error.");
! 460: robj = KpoInteger(-1);
! 461: return(robj);
! 462: }
! 463: if (n == 0) {
! 464: errorMsg1s("Read returned without data.");
! 465: }
! 466:
! 467: robj = KpoInteger((int)((unsigned char)data[0]));
! 468: return(robj);
! 469:
! 470: }
! 471:
! 472: /* [ integer socketid, int ]
! 473: integer */
! 474: struct object KsocketWriteByte(struct object obj) {
! 475: struct object ob1;
! 476: struct object ob2;
! 477: int socketid;
! 478: int r;
! 479: char data[2];
! 480: if (obj.tag != Sarray) {
! 481: errorMsg1s("KsocketWriteByte([integer socketid, int])");
! 482: }
! 483: if (getoaSize(obj) < 2) {
! 484: errorMsg1s("KsocketWriteByte([integer socketid, int])");
! 485: }
! 486: ob1 = getoa(obj,0);
! 487: ob2 = getoa(obj,1);
! 488: if (ob1.tag != Sinteger) {
! 489: errorMsg1s("KsocketWriteByte([integer socketid, int]) : the first argument must be an integer.");
! 490: }
! 491: socketid = KopInteger(ob1);
! 492: if (ob2.tag != Sinteger) {
! 493: errorMsg1s("KsocketWriteByte([integer socketid, int]) : the second argument must be a string.");
! 494: }
! 495: data[0] = KopInteger(ob2);
! 496: r = write(socketid,data, 1);
! 497: return(KpoInteger(r));
! 498: }
! 499:
! 500: struct object Kplugin_sm1Socket(char *key,struct object obj) {
! 501: struct object robj = NullObject;
! 502: if (strcmp(key,"open") == 0) {
! 503: robj = KsocketOpen(obj);
! 504: }else if (strcmp(key,"connect") == 0) {
! 505: robj = KsocketConnect(obj);
! 506: }else if (strcmp(key,"accept") == 0) {
! 507: robj = KsocketAccept(obj);
! 508: }else if (strcmp(key,"select") == 0) {
! 509: robj = KsocketSelect(obj);
! 510: }else if (strcmp(key,"mselect") == 0) {
! 511: robj = KsocketSelectMulti(obj);
! 512: }else if (strcmp(key,"read") == 0) {
! 513: robj = KsocketRead(obj);
! 514: }else if (strcmp(key,"write") == 0) {
! 515: robj = KsocketWrite(obj);
! 516: }else if (strcmp(key,"read") == 0) {
! 517: robj = KsocketRead(obj);
! 518: }else if (strcmp(key,"readByte") == 0) {
! 519: robj = KsocketReadByte(obj);
! 520: }else if (strcmp(key,"writeByte") == 0) {
! 521: robj = KsocketWriteByte(obj);
! 522: }else if (strcmp(key,"close") == 0) {
! 523: robj = KsocketClose(obj);
! 524: }else {
! 525: errorMsg1s("Unknown tag for sm1.socket");
! 526: }
! 527: return(robj);
! 528: }
! 529:
! 530:
! 531:
! 532:
! 533:
! 534:
! 535:
! 536:
! 537:
! 538:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>