6e05e63aa2a5ab72c12d569db81d8ff27607acbb
[IRC.git] / Robust / src / Runtime / socket.c
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 "SimpleHash.h"
9 #include "GenericHashtable.h"
10
11 extern struct RuntimeHash *fdtoobject;
12
13 int CALL12(___ServerSocket______createSocket____I, int port, struct ___ServerSocket___ * ___this___, int port) {
14   int fd;
15
16   int n=1;
17   struct sockaddr_in sin;
18
19   bzero (&sin, sizeof (sin));
20   sin.sin_family = AF_INET;
21   sin.sin_port = htons (port);
22   sin.sin_addr.s_addr = htonl (INADDR_ANY);
23   fd=socket(AF_INET, SOCK_STREAM, 0);
24   if (fd<0) {
25 #ifdef DEBUG
26     perror(NULL);
27     printf("createSocket error #1\n");
28 #endif
29 #ifdef TASK
30     longjmp(error_handler,5);
31 #else
32 #ifdef THREADS
33     threadexit();
34 #else
35     exit(-1);
36 #endif
37 #endif
38   }
39
40   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof (n)) < 0) {
41     close(fd);
42 #ifdef DEBUG
43     perror(NULL);
44     printf("createSocket error #2\n");
45 #endif
46 #ifdef TASK
47     longjmp(error_handler,6);
48 #else
49 #ifdef THREADS
50     threadexit();
51 #else
52     exit(-1);
53 #endif
54 #endif
55   }
56
57 #ifdef TASK
58   fcntl(fd, F_SETFD, 1);
59   fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
60 #endif
61
62   /* bind to port */
63   if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))<0) { 
64     close (fd);
65 #ifdef DEBUG
66     perror(NULL);
67     printf("createSocket error #3\n");
68 #endif
69 #ifdef TASK
70     longjmp(error_handler,7);
71 #else
72 #ifdef THREADS
73     threadexit();
74 #else
75     exit(-1);
76 #endif
77 #endif
78   }
79
80   /* listen */
81   if (listen(fd, 5)<0) { 
82     close (fd);
83 #ifdef DEBUG
84     perror(NULL);
85     printf("createSocket error #4\n");
86 #endif
87 #ifdef TASK
88     longjmp(error_handler,8);
89 #else
90 #ifdef THREADS
91     threadexit();
92 #else
93     exit(-1);
94 #endif
95 #endif
96   }
97
98   /* Store the fd/socket object mapping */
99 #ifdef TASK
100   RuntimeHashadd(fdtoobject, fd, (int) VAR(___this___));
101   addreadfd(fd);
102 #endif
103   return fd;
104 }
105
106 int CALL02(___ServerSocket______nativeaccept____L___Socket___,struct ___ServerSocket___ * ___this___, struct ___Socket___ * ___s___) {
107   struct sockaddr_in sin;
108   unsigned int sinlen=sizeof(sin);
109   int fd=VAR(___this___)->___fd___;
110   int newfd;
111 #ifdef THREADS
112 #ifdef PRECISE_GC
113   struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
114 #endif
115 #endif
116   newfd=accept(fd, (struct sockaddr *)&sin, &sinlen);
117 #ifdef THREADS 
118 #ifdef PRECISE_GC
119   restartaftergc(tmp);
120 #endif
121 #endif
122   if (newfd<0) { 
123 #ifdef DEBUG
124     perror(NULL);
125     printf("acceptSocket error #1\n");
126 #endif
127 #ifdef TASK
128     longjmp(error_handler,9);
129 #else
130 #ifdef THREADS
131     threadexit();
132 #else
133     exit(-1);
134 #endif
135 #endif
136   }
137 #ifdef TASK
138   fcntl(newfd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
139   RuntimeHashadd(fdtoobject, newfd, (int) VAR(___s___));
140   addreadfd(newfd);
141   flagorand(VAR(___this___),0,0xFFFFFFFE);
142 #endif
143   return newfd;
144 }
145
146 void CALL02(___Socket______nativeWrite_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
147   int fd=VAR(___this___)->___fd___;
148   int length=VAR(___b___)->___length___;
149   char * charstr=((char *)& VAR(___b___)->___length___)+sizeof(int);
150   while(1) {
151     int bytewritten=write(fd, charstr, length);
152     if (bytewritten==-1&&errno==EAGAIN)
153       continue;
154
155     if (bytewritten!=length) {
156       perror("ERROR IN NATIVEWRITE");
157     }
158     break;
159   }
160 }
161
162 int CALL02(___Socket______nativeRead_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
163   int fd=VAR(___this___)->___fd___;
164   int length=VAR(___b___)->___length___;
165
166   char * charstr=malloc(length);
167   
168 #ifdef THREADS
169 #ifdef PRECISE_GC
170   struct listitem *tmp=stopforgc((struct garbagelist *)___params___);
171 #endif
172 #endif
173   int byteread=read(fd, charstr, length);
174 #ifdef THREADS
175 #ifdef PRECISE_GC
176   restartaftergc(tmp);
177 #endif
178 #endif
179
180   {
181     int i;
182     for(i=0;i<byteread;i++) {
183       (((char *)& VAR(___b___)->___length___)+sizeof(int))[i]=charstr[i];
184     }
185     free(charstr);
186   }
187
188
189   if (byteread<0) {
190     printf("ERROR IN NATIVEREAD\n");
191   }
192 #ifdef TASK
193   flagorand(VAR(___this___),0,0xFFFFFFFE);
194 #endif
195   return byteread;
196 }
197
198 void CALL01(___Socket______nativeClose____, struct ___Socket___ * ___this___) {
199   int fd=VAR(___this___)->___fd___;
200   int data;
201 #ifdef TASK
202   RuntimeHashget(fdtoobject, fd, &data);
203   RuntimeHashremove(fdtoobject, fd, data);
204   removereadfd(fd);
205   flagorand(VAR(___this___),0,0xFFFFFFFE);
206 #endif
207   close(fd);
208 }