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