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