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