on master help sign in
Split out Windows versions of some rts files

This allows the introduction of Posix functionality, parallel Windows implementations can then be put in the windows/ directory.

commit380a87477bf75fc3bda1dd7fe07765236fdcaf2a authorNiklas Larsson <niklas@mm.st> dateWed 26 Feb 2014, 20:49 (13 years ago) parent3bc4846
5 files changed+329−4
rts/Makefile+12−4 rts/windows/idris_net.c+185 rts/windows/idris_net.h+45 rts/windows/idris_stdfgn.c+63 rts/windows/idris_stdfgn.h+24
rts/Makefile+12−4
@@ -1,12 +1,20 @@
11include ../config.mk
22
3−OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_stdfgn.o \
4− idris_bitstring.o idris_net.o idris_opts.o idris_stats.o mini-gmp.o
5−HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_stdfgn.h \
6− idris_bitstring.h idris_net.h idris_opts.h idris_stats.h mini-gmp.h
3+OBJS = idris_rts.o idris_heap.o idris_gc.o idris_gmp.o idris_bitstring.o \
4+ idris_opts.o idris_stats.o mini-gmp.o
5+HDRS = idris_rts.h idris_heap.h idris_gc.h idris_gmp.h idris_bitstring.h \
6+ idris_opts.h idris_stats.h mini-gmp.h
77CFLAGS:=-fPIC $(CFLAGS)
88CFLAGS += $(GMP_INCLUDE_DIR) $(GMP)
99
10+ifeq ($(OS), windows)
11+ OBJS += windows/idris_stdfgn.o windows/idris_net.o
12+ HDRS += windows/idris_stdfgn.h windows/idris_net.h
13+else
14+ OBJS += idris_stdfgn.o idris_net.o
15+ HDRS += idris_stdfgn.h idris_net.h
16+endif
17+
1018LIBTARGET = libidris_rts.a
1119
1220build: $(LIBTARGET) $(DYLIBTARGET)
rts/windows/idris_net.cnew file+185
@@ -0,0 +1,185 @@
1+// C-Side of the Idris network library
2+// (C) Simon Fowler, 2014
3+// MIT Licensed. Have fun!
4+#include "idris_net.h"
5+
6+#include <errno.h>
7+#include <stdbool.h>
8+#include <stdlib.h>
9+#include <stdio.h>
10+#include <string.h>
11+#include <Winsock2.h>
12+#include <Ws2tcpip.h>
13+
14+static int socket_inited = 0;
15+static WSADATA wsa_data;
16+
17+void* idrnet_malloc(int size) {
18+ return malloc(size);
19+}
20+
21+void idrnet_free(void* ptr) {
22+ free(ptr);
23+}
24+
25+static int check_init()
26+{
27+ if (!socket_inited) {
28+ int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
29+ if (result == NO_ERROR) {
30+ socket_inited = 1;
31+ }
32+ }
33+ return socket_inited;
34+}
35+
36+int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
37+ struct addrinfo hints;
38+ struct addrinfo* address_res;
39+ // Convert port into string
40+ char str_port[8];
41+ sprintf(str_port, "%d", port);
42+
43+ if (!check_init()) {
44+ return -1;
45+ }
46+ // Set up hints structure
47+ memset(&hints, 0, sizeof(hints)); // zero out hints
48+ hints.ai_family = family;
49+ hints.ai_socktype = socket_type;
50+
51+ // If the length of the hostname is 0 (i.e, it was set to Nothing in Idris)
52+ // then we want to instruct the C library to fill in the IP automatically
53+ if (strlen(host) == 0) {
54+ hints.ai_flags = AI_PASSIVE; // fill in IP automatically
55+ }
56+
57+ int addr_res = getaddrinfo(host, str_port, &hints, &address_res);
58+ if (addr_res == -1) {
59+ return -1;
60+ }
61+
62+ int bind_res = bind(sockfd, address_res->ai_addr, address_res->ai_addrlen);
63+ if (bind_res == -1) {
64+ return -1;
65+ }
66+
67+ return 0;
68+}
69+
70+int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port) {
71+ char str_port[8];
72+ sprintf(str_port, "%d", port);
73+ struct addrinfo hints;
74+ struct addrinfo* remote_host;
75+
76+ if (!check_init()) {
77+ return -1;
78+ }
79+ // Set up hints structure for getaddrinfo
80+ memset(&hints, 0, sizeof(hints));
81+ hints.ai_family = family;
82+ hints.ai_socktype = socket_type;
83+
84+ // Get info about the remote host (DNS lookup etc)
85+ int addr_res = getaddrinfo(host, str_port, &hints, &remote_host);
86+ if (addr_res == -1) {
87+ return -1;
88+ }
89+
90+ int connect_res = connect(sockfd, remote_host->ai_addr, remote_host->ai_addrlen);
91+ if (connect_res == -1) {
92+ return -1;
93+ }
94+
95+ return 0;
96+}
97+
98+
99+int idrnet_sockaddr_family(void* sockaddr) {
100+ struct sockaddr* addr = (struct sockaddr*) sockaddr;
101+ return (int) addr->sa_family;
102+}
103+
104+char* idrnet_sockaddr_ipv4(void* sockaddr) {
105+ struct sockaddr_in* addr = (struct sockaddr_in*) sockaddr;
106+ char* ip_addr = (char*) malloc(sizeof(char) * INET_ADDRSTRLEN);
107+ inet_ntop(AF_INET, &(addr->sin_addr), ip_addr, INET_ADDRSTRLEN);
108+ return ip_addr;
109+}
110+
111+void* idrnet_create_sockaddr() {
112+ return malloc(sizeof(struct sockaddr_storage));
113+}
114+
115+
116+int idrnet_accept(int sockfd, void* sockaddr) {
117+ struct sockaddr* addr = (struct sockaddr*) sockaddr;
118+ socklen_t addr_size = 0;
119+ if (!check_init()) {
120+ return -1;
121+ }
122+ return accept(sockfd, addr, &addr_size);
123+}
124+
125+int idrnet_send(int sockfd, char* data) {
126+ int len = strlen(data); // For now.
127+ if (!check_init()) {
128+ return -1;
129+ }
130+ return send(sockfd, (void*) data, len, 0);
131+}
132+
133+int idrnet_send_buf(int sockfd, void* data, int len) {
134+ if (!check_init()) {
135+ return -1;
136+ }
137+ return send(sockfd, data, len, 0);
138+}
139+
140+void* idrnet_recv(int sockfd, int len) {
141+ if (!check_init()) {
142+ return -1;
143+ }
144+ idrnet_recv_result* res_struct =
145+ (idrnet_recv_result*) malloc(sizeof(idrnet_recv_result));
146+
147+ char* buf = malloc(len + 1);
148+ int recv_res = recv(sockfd, buf, len, 0);
149+ res_struct->result = recv_res;
150+
151+ if (recv_res > 0) { // Data was received
152+ buf[recv_res + 1] = 0x00; // Null-term, so Idris can interpret it
153+ }
154+ res_struct->payload = (void*) buf;
155+ return (void*) res_struct;
156+}
157+
158+int idrnet_recv_buf(int sockfd, void* buf, int len) {
159+ if (!check_init()) {
160+ return -1;
161+ }
162+ return recv(sockfd, buf, len, 0);
163+}
164+
165+int idrnet_get_recv_res(void* res_struct) {
166+ return (((idrnet_recv_result*) res_struct)->result);
167+}
168+
169+void* idrnet_get_recv_payload(void* res_struct) {
170+ return (((idrnet_recv_result*) res_struct)->payload);
171+}
172+
173+void idrnet_free_recv_struct(void* res_struct) {
174+ idrnet_recv_result* i_res_struct =
175+ (idrnet_recv_result*) res_struct;
176+ if (i_res_struct->payload != NULL) {
177+ free(i_res_struct->payload);
178+ }
179+ free(res_struct);
180+}
181+
182+int idrnet_errno() {
183+ return errno;
184+}
185+
rts/windows/idris_net.hnew file+45
@@ -0,0 +1,45 @@
1+#ifndef IDRISNET_H
2+#define IDRISNET_H
3+
4+
5+typedef struct idrnet_recv_result {
6+ int result;
7+ void* payload;
8+} idrnet_recv_result;
9+
10+// Memory management functions
11+void* idrnet_malloc(int size);
12+void idrnet_free(void* ptr);
13+
14+// Gets value of errno
15+int idrnet_errno();
16+
17+// Bind
18+int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port);
19+
20+// Connect
21+int idrnet_connect(int sockfd, int family, int socket_type, char* host, int port);
22+
23+// Accessor functions for struct_sockaddr
24+int idrnet_sockaddr_family(void* sockaddr);
25+char* idrnet_sockaddr_ipv4(void* sockaddr);
26+void* idrnet_create_sockaddr();
27+
28+// Accept
29+int idrnet_accept(int sockfd, void* sockaddr);
30+
31+// Send
32+int idrnet_send(int sockfd, char* data);
33+int idrnet_send_buf(int sockfd, void* data, int len);
34+
35+// Receive
36+// Creates a result structure containing result and payload
37+void* idrnet_recv(int sockfd, int len);
38+// Receives directly into a buffer
39+int idrnet_recv_buf(int sockfd, void* buf, int len);
40+
41+// Receive structure accessors
42+int idrnet_get_recv_res(void* res_struct);
43+void* idrnet_get_recv_payload(void* res_struct);
44+void idrnet_free_recv_struct(void* res_struct);
45+#endif
rts/windows/idris_stdfgn.cnew file+63
@@ -0,0 +1,63 @@
1+#include "idris_stdfgn.h"
2+#include "../idris_rts.h"
3+#include <fcntl.h>
4+#include <stdio.h>
5+
6+extern char** environ;
7+
8+void putStr(char* str) {
9+ printf("%s", str);
10+}
11+
12+void* fileOpen(char* name, char* mode) {
13+ FILE* f = fopen(name, mode);
14+ return (void*)f;
15+}
16+
17+void fileClose(void* h) {
18+ FILE* f = (FILE*)h;
19+ fclose(f);
20+}
21+
22+int fileEOF(void* h) {
23+ FILE* f = (FILE*)h;
24+ return feof(f);
25+}
26+
27+int fileError(void* h) {
28+ FILE* f = (FILE*)h;
29+ return ferror(f);
30+}
31+
32+void fputStr(void* h, char* str) {
33+ FILE* f = (FILE*)h;
34+ fputs(str, f);
35+}
36+
37+int fpoll(void* h)
38+{
39+ return 0;
40+}
41+
42+void* do_popen(const char* cmd, const char* mode) {
43+ FILE* f = _popen(cmd, mode);
44+// int d = fileno(f);
45+// fcntl(d, F_SETFL, O_NONBLOCK);
46+ return f;
47+}
48+
49+int isNull(void* ptr) {
50+ return ptr==NULL;
51+}
52+
53+int idris_eqPtr(void* x, void* y) {
54+ return x==y;
55+}
56+
57+void* idris_stdin() {
58+ return (void*)stdin;
59+}
60+
61+char* getEnvPair(int i) {
62+ return *(environ + i);
63+}
rts/windows/idris_stdfgn.hnew file+24
@@ -0,0 +1,24 @@
1+#ifndef _IDRISSTDFGN_H
2+#define _IDRISSTDFGN_H
3+
4+// A collection of useful standard functions to be used by the prelude.
5+
6+void putStr(char* str);
7+//char* readStr();
8+
9+void* fileOpen(char* f, char* mode);
10+void fileClose(void* h);
11+int fileEOF(void* h);
12+int fileError(void* h);
13+void fputStr(void*h, char* str);
14+
15+void* do_popen(const char* cmd, const char* mode);
16+int fpoll(void* h);
17+
18+int idris_eqPtr(void* x, void* y);
19+int isNull(void* ptr);
20+void* idris_stdin();
21+
22+char* getEnvPair(int i);
23+
24+#endif