get specjbb compiling again...get rid of annoying warnings...still left with large...
[IRC.git] / Robust / src / Runtime / socket.c
1 #include "runtime.h"
2 #include "structdefs.h"
3 #ifndef MULTICORE
4 #include <fcntl.h>
5 #include <sys/socket.h>
6 #include <arpa/inet.h>
7 #include <strings.h>
8 #include <netdb.h>
9 #include <netinet/tcp.h>
10 #include <errno.h>
11 #endif
12 #include "SimpleHash.h"
13 #include "GenericHashtable.h"
14 #include "methodheaders.h"
15
16 struct RuntimeHash *fdtoobject;
17
18 #ifdef D___Socket______nativeConnect____I__AR_B_I
19 int CALL24(___Socket______nativeConnect____I__AR_B_I, int ___fd___, int ___port___, struct ___Socket___ * ___this___, int ___fd___, struct ArrayObject * ___address___,int ___port___) {
20 #ifdef MULTICORE
21   // not supported in MULTICORE version
22   return -1;
23 #else
24   struct sockaddr_in sin;
25   int rc;
26
27   bzero(&sin, sizeof(sin));
28   sin.sin_family= AF_INET;
29   sin.sin_port=htons(___port___);
30   sin.sin_addr.s_addr=htonl(*(int *)(((char *)&VAR(___address___)->___length___)+sizeof(int)));
31 #if defined(THREADS)||defined(DSTM)||defined(STM)
32 #ifdef PRECISE_GC
33   stopforgc((struct garbagelist *)___params___);
34 #endif
35 #endif
36   do {
37     rc = connect(___fd___, (struct sockaddr *) &sin, sizeof(sin));
38   } while (rc<0 && errno==EINTR); /* repeat if interrupted */
39 #if defined(THREADS)||defined(DSTM)||defined(STM)
40 #ifdef PRECISE_GC
41   restartaftergc();
42 #endif
43 #endif
44
45   {
46   int flag = 1;
47   setsockopt(___fd___, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
48   }
49   if (rc<0) goto error;
50
51 #ifdef TASK
52   //Make non-blocking
53   fcntl(___fd___, F_SETFD, 1);
54   fcntl(___fd___, F_SETFL, fcntl(___fd___, F_GETFL)|O_NONBLOCK);
55   RuntimeHashadd(fdtoobject, ___fd___, (int) VAR(___this___));
56   addreadfd(___fd___);
57 #endif
58
59   return 0;
60
61 error:
62   close(___fd___);
63   return -1;
64 #endif
65 }
66 #endif
67
68 #ifdef TASK
69 #ifdef D___Socket______nativeBindFD____I
70 int CALL12(___Socket______nativeBindFD____I, int ___fd___, struct ___Socket___ * ___this___, int ___fd___) {
71 #ifdef MULTICORE
72 #else
73   if (RuntimeHashcontainskey(fdtoobject, ___fd___))
74     RuntimeHashremovekey(fdtoobject, ___fd___);
75   RuntimeHashadd(fdtoobject, ___fd___, (int) VAR(___this___));
76   addreadfd(___fd___);
77 #endif
78   return 0;
79 }
80 #endif
81 #endif
82
83 #ifdef D___Socket______nativeBind_____AR_B_I
84 int CALL12(___Socket______nativeBind_____AR_B_I, int ___port___,  struct ArrayObject * ___address___, int ___port___) {
85 #ifdef MULTICORE
86   // not supported in MULTICORE version
87   return -1;
88 #else
89   int fd;
90   int rc;
91   socklen_t sa_size;
92   struct sockaddr_in sin;
93   bzero(&sin, sizeof(sin));
94   sin.sin_family= AF_INET;
95   sin.sin_port=0;
96   sin.sin_addr.s_addr=INADDR_ANY;
97
98   fd=socket(AF_INET, SOCK_STREAM, 0);
99   if (fd<0) {
100 #ifdef DEBUG
101     perror(NULL);
102     printf("createSocket error in nativeBind\n");
103 #endif
104 #ifdef TASK
105     longjmp(error_handler,12);
106 #else
107 #ifdef THREADS
108     threadexit();
109 #else
110     exit(-1);
111 #endif
112 #endif
113   }
114
115   rc = bind(fd, (struct sockaddr *) &sin, sizeof(sin));
116   if (rc<0) goto error;
117
118   sa_size = sizeof(sin);
119   rc = getsockname(fd, (struct sockaddr *) &sin, &sa_size);
120   if (rc<0) goto error;
121
122   return fd;
123
124 error:
125   close(fd);
126 #ifdef DEBUG
127   perror(NULL);
128   printf("createSocket error #2 in nativeBind\n");
129 #endif
130 #ifdef TASK
131   longjmp(error_handler,13);
132 #else
133 #ifdef THREADS
134   threadexit();
135 #else
136   exit(-1);
137 #endif
138 #endif
139 #endif
140 }
141 #endif
142
143 #ifdef D___InetAddress______getHostByName_____AR_B
144 struct ArrayObject * CALL01(___InetAddress______getHostByName_____AR_B, struct ArrayObject * ___hostname___) {
145 #ifdef MULTICORE
146   // not supported in MULTICORE version
147   return NULL;
148 #else
149 //struct ArrayObject * CALL01(___InetAddress______getHostByName_____AR_B, struct ___ArrayObject___ * ___hostname___) {
150   int length=VAR(___hostname___)->___length___;
151   int i,j,n;
152   char * str=malloc(length+1);
153   struct hostent *h;
154   struct ArrayObject * arraybytearray;
155
156   for(i=0; i<length; i++) {
157     str[i]=(((char *)&VAR(___hostname___)->___length___)+sizeof(int))[i];
158   }
159   str[length]=0;
160   h=gethostbyname(str);
161   free(str);
162
163         if (h != NULL) {
164                 for (n=0; h->h_addr_list[n]; n++) /* do nothing */ ;
165
166 #ifdef PRECISE_GC
167   arraybytearray=allocate_newarray(___params___,BYTEARRAYARRAYTYPE,n);
168 #else
169   arraybytearray=allocate_newarray(BYTEARRAYARRAYTYPE,n);
170 #endif
171   for(i=0; i<n; i++) {
172     struct ArrayObject *bytearray;
173 #ifdef PRECISE_GC
174     {
175       INTPTR ptrarray[]={1, (INTPTR) ___params___, (INTPTR)arraybytearray};
176       bytearray=allocate_newarray(&ptrarray,BYTEARRAYTYPE,h->h_length);
177       arraybytearray=(struct ArrayObject *) ptrarray[2];
178     }
179 #else
180     bytearray=allocate_newarray(BYTEARRAYTYPE,h->h_length);
181 #endif
182     ((void **)&((&arraybytearray->___length___)[1]))[i]=bytearray;
183     {
184       int ha=ntohl(*(int *)h->h_addr_list[i]);
185       (&bytearray->___length___)[1]=ha;
186     }
187   }
188
189   return arraybytearray;
190         } else {
191                 return NULL;
192         }
193 #endif
194 }
195 #endif
196
197 #ifdef D___ServerSocket______createSocket____I
198 int CALL12(___ServerSocket______createSocket____I, int port, struct ___ServerSocket___ * ___this___, int port) {
199 #ifdef MULTICORE
200   // not supported in MULTICORE version
201   return -1;
202 #else
203   int fd;
204
205   int n=1;
206   struct sockaddr_in sin;
207
208   bzero(&sin, sizeof(sin));
209   sin.sin_family = AF_INET;
210   sin.sin_port = htons(port);
211   sin.sin_addr.s_addr = htonl(INADDR_ANY);
212   fd=socket(AF_INET, SOCK_STREAM, 0);
213   if (fd<0) {
214 #ifdef DEBUG
215     perror(NULL);
216     printf("createSocket error #1\n");
217 #endif
218 #ifdef TASK
219     longjmp(error_handler,5);
220 #else
221 #ifdef THREADS
222     threadexit();
223 #else
224     exit(-1);
225 #endif
226 #endif
227   }
228
229   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof (n)) < 0) {
230     close(fd);
231 #ifdef DEBUG
232     perror("");
233     printf("createSocket error #2\n");
234 #endif
235 #ifdef TASK
236     longjmp(error_handler,6);
237 #else
238 #ifdef THREADS
239     threadexit();
240 #else
241     exit(-1);
242 #endif
243 #endif
244   }
245
246 #ifdef MAC
247   if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof (n)) < 0) {
248     perror("socket");
249     exit(-1);
250   }
251 #endif
252
253 #ifdef TASK
254   fcntl(fd, F_SETFD, 1);
255   fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
256 #endif
257
258   /* bind to port */
259   if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))<0) {
260     close(fd);
261 #ifdef DEBUG
262     perror("");
263     printf("createSocket error #3\n");
264 #endif
265 #ifdef TASK
266     longjmp(error_handler,7);
267 #else
268 #ifdef THREADS
269     threadexit();
270 #else
271     exit(-1);
272 #endif
273 #endif
274   }
275
276   /* listen */
277   if (listen(fd, 5)<0) {
278     close(fd);
279 #ifdef DEBUG
280     perror("");
281     printf("createSocket error #4\n");
282 #endif
283 #ifdef TASK
284     longjmp(error_handler,8);
285 #else
286 #ifdef THREADS
287     threadexit();
288 #else
289     exit(-1);
290 #endif
291 #endif
292   }
293
294   /* Store the fd/socket object mapping */
295 #ifdef TASK
296   RuntimeHashadd(fdtoobject, fd, (int) VAR(___this___));
297   addreadfd(fd);
298 #endif
299   return fd;
300 #endif
301 }
302 #endif
303
304 #ifdef D___ServerSocket______nativeaccept____L___Socket___
305 int CALL02(___ServerSocket______nativeaccept____L___Socket___,struct ___ServerSocket___ * ___this___, struct ___Socket___ * ___s___) {
306 #ifdef MULTICORE
307   // not supported in MULTICORE version
308   return -1;
309 #else
310   struct sockaddr_in sin;
311   unsigned int sinlen=sizeof(sin);
312   int fd=VAR(___this___)->___fd___;
313   int newfd;
314 #if defined(THREADS)||defined(DSTM)||defined(STM)
315 #ifdef PRECISE_GC
316   stopforgc((struct garbagelist *)___params___);
317 #endif
318 #endif
319   newfd=accept(fd, (struct sockaddr *)&sin, &sinlen);
320   int flag = 1;
321   setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
322 #if defined(THREADS)||defined(DSTM)||defined(STM)
323 #ifdef PRECISE_GC
324   restartaftergc();
325 #endif
326 #endif
327   if (newfd<0) {
328 #ifdef DEBUG
329     perror(NULL);
330     printf("acceptSocket error #1\n");
331 #endif
332 #ifdef TASK
333     longjmp(error_handler,9);
334 #else
335 #ifdef THREADS
336     threadexit();
337 #else
338     exit(-1);
339 #endif
340 #endif
341   }
342 #ifdef TASK
343   fcntl(newfd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
344   RuntimeHashadd(fdtoobject, newfd, (int) VAR(___s___));
345   addreadfd(newfd);
346 #ifdef MULTICORE
347   flagorand(VAR(___this___),0,0xFFFFFFFE,NULL,0);
348   enqueueObject(VAR(___this___), NULL, 0);
349 #else
350   flagorand(VAR(___this___),0,0xFFFFFFFE);
351   enqueueObject(VAR(___this___));
352 #endif
353 #endif
354   return newfd;
355 #endif
356 }
357 #endif
358
359 #ifdef D___Socket______nativeWrite_____AR_B_I_I
360 void CALL24(___Socket______nativeWrite_____AR_B_I_I, int offset, int length, struct ___Socket___ * ___this___, struct ArrayObject * ___b___, int offset, int length) {
361 #ifdef MULTICORE
362 #else
363   int fd=VAR(___this___)->___fd___;
364   char * charstr=((char *)&VAR(___b___)->___length___)+sizeof(int)+offset;
365   while(1) {
366     int offset=0;
367     int bytewritten;
368     while(length>0) {
369       bytewritten=write(fd, &charstr[offset], length);
370       if (bytewritten==-1&&errno!=EAGAIN)
371         break;
372       length-=bytewritten;
373       offset+=bytewritten;
374     }
375
376     if (length!=0) {
377       perror("ERROR IN NATIVEWRITE");
378       printf("error=%d remaining bytes %d\n",errno, length);
379     }
380     break;
381   }
382 #endif
383 }
384 #endif
385
386
387 #ifdef D___Socket______nativeRead_____AR_B
388 int CALL02(___Socket______nativeRead_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
389 #ifdef MULTICORE
390   return -1;
391 #else
392   int fd=VAR(___this___)->___fd___;
393   int length=VAR(___b___)->___length___;
394
395   char * charstr=malloc(length);
396
397 #if defined(THREADS)||defined(DSTM)||defined(STM)
398 #ifdef PRECISE_GC
399   stopforgc((struct garbagelist *)___params___);
400 #endif
401 #endif
402   int byteread=-1;
403
404   do {
405     byteread=read(fd, charstr, length);
406   } while(byteread==-1&&errno==EINTR);
407 #if defined(THREADS)||defined(DSTM)||defined(STM)
408 #ifdef PRECISE_GC
409   restartaftergc();
410 #endif
411 #endif
412
413   {
414     int i;
415     for(i=0; i<byteread; i++) {
416       (((char *)&VAR(___b___)->___length___)+sizeof(int))[i]=charstr[i];
417     }
418     free(charstr);
419   }
420
421
422   if (byteread<0) {
423 #ifndef MULTICORE
424     printf("ERROR IN NATIVEREAD\n");
425     perror("");
426 #endif
427   }
428 #ifdef TASK
429 #ifdef MULTICORE
430   flagorand(VAR(___this___),0,0xFFFFFFFE,NULL,0);
431   enqueueObject(VAR(___this___), NULL, 0);
432 #else
433   flagorand(VAR(___this___),0,0xFFFFFFFE);
434   enqueueObject(VAR(___this___));
435 #endif
436 #endif
437   return byteread;
438 #endif
439 }
440 #endif
441
442 #ifdef D___Socket______nativeClose____
443 void CALL01(___Socket______nativeClose____, struct ___Socket___ * ___this___) {
444 #ifdef MULTICORE
445 #else
446   int fd=VAR(___this___)->___fd___;
447   int data;
448 #ifdef TASK
449   RuntimeHashget(fdtoobject, fd, &data);
450   RuntimeHashremove(fdtoobject, fd, data);
451   removereadfd(fd);
452   flagorand(VAR(___this___),0,0xFFFFFFFE);
453   enqueueObject(VAR(___this___));
454 #endif
455   close(fd);
456 #endif
457 }
458 #endif