support for non-bristlecone socket i/o
[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     longjmp(error_handler,5);
30   }
31
32   if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof (n)) < 0) {
33     close(fd);
34 #ifdef DEBUG
35     perror(NULL);
36     printf("createSocket error #2\n");
37 #endif
38     longjmp(error_handler, 6);
39   }
40
41 #ifdef TASK
42   fcntl(fd, F_SETFD, 1);
43   fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
44 #endif
45
46   /* bind to port */
47   if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))<0) { 
48     close (fd);
49 #ifdef DEBUG
50     perror(NULL);
51     printf("createSocket error #3\n");
52 #endif
53     longjmp(error_handler, 7);
54   }
55
56   /* listen */
57   if (listen(fd, 5)<0) { 
58     close (fd);
59 #ifdef DEBUG
60     perror(NULL);
61     printf("createSocket error #4\n");
62 #endif
63     longjmp(error_handler, 8);
64   }
65
66   /* Store the fd/socket object mapping */
67 #ifdef TASK
68   RuntimeHashadd(fdtoobject, fd, (int) VAR(___this___));
69   addreadfd(fd);
70 #endif
71   return fd;
72 }
73
74 int CALL02(___ServerSocket______nativeaccept____L___Socket___,struct ___ServerSocket___ * ___this___, struct ___Socket___ * ___s___) {
75   struct sockaddr_in sin;
76   unsigned int sinlen=sizeof(sin);
77   int fd=VAR(___this___)->___fd___;
78   int newfd;
79   newfd=accept(fd, (struct sockaddr *)&sin, &sinlen);
80
81
82   if (newfd<0) { 
83 #ifdef DEBUG
84     perror(NULL);
85     printf("acceptSocket error #1\n");
86 #endif
87     longjmp(error_handler, 9);
88   }
89 #ifdef TASK
90   fcntl(newfd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
91   RuntimeHashadd(fdtoobject, newfd, (int) VAR(___s___));
92   addreadfd(newfd);
93   flagorand(VAR(___this___),0,0xFFFFFFFE);
94 #endif
95
96   return newfd;
97 }
98
99
100 void CALL02(___Socket______nativeWrite_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
101   int fd=VAR(___this___)->___fd___;
102   int length=VAR(___b___)->___length___;
103   char * charstr=((char *)& VAR(___b___)->___length___)+sizeof(int);
104   while(1) {
105     int bytewritten=write(fd, charstr, length);
106     if (bytewritten==-1&&errno==EAGAIN)
107       continue;
108
109     if (bytewritten!=length) {
110       perror("ERROR IN NATIVEWRITE");
111     }
112     break;
113   }
114 }
115
116 int CALL02(___Socket______nativeRead_____AR_B, struct ___Socket___ * ___this___, struct ArrayObject * ___b___) {
117   int fd=VAR(___this___)->___fd___;
118   int length=VAR(___b___)->___length___;
119   char * charstr=((char *)& VAR(___b___)->___length___)+sizeof(int);
120   int byteread=read(fd, charstr, length);
121   
122   if (byteread<0) {
123     printf("ERROR IN NATIVEREAD\n");
124   }
125 #ifdef TASK
126   flagorand(VAR(___this___),0,0xFFFFFFFE);
127 #endif
128   return byteread;
129 }
130
131 void CALL01(___Socket______nativeClose____, struct ___Socket___ * ___this___) {
132   int fd=VAR(___this___)->___fd___;
133   int data;
134 #ifdef TASK
135   RuntimeHashget(fdtoobject, fd, &data);
136   RuntimeHashremove(fdtoobject, fd, data);
137   removereadfd(fd);
138   flagorand(VAR(___this___),0,0xFFFFFFFE);
139 #endif
140   close(fd);
141 }