4 #include <stdlib.h> |
4 #include <stdlib.h> |
5 #include <sys/types.h> |
5 #include <sys/types.h> |
6 #include <sys/socket.h> |
6 #include <sys/socket.h> |
7 #include <netdb.h> |
7 #include <netdb.h> |
8 #include <unistd.h> |
8 #include <unistd.h> |
|
9 #include <fcntl.h> |
9 #include <string.h> |
10 #include <string.h> |
10 #include <assert.h> |
11 #include <assert.h> |
11 |
12 |
12 /* |
13 /* |
13 * Our sock_stream_methods.read method |
14 * Our sock_stream_methods.read method |
14 */ |
15 */ |
15 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t len) |
16 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len) |
16 { |
17 { |
17 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
18 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
18 int ret; |
19 int ret; |
19 |
20 |
20 // map directly to read(2) |
21 // map directly to read(2) |
21 if ((ret = read(sock->fd, buf, len)) < 0) |
22 if ((ret = read(sock->fd, buf, *len)) < 0) |
22 // errno |
23 // errno |
23 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ); |
24 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ); |
24 |
25 |
25 else |
26 // bytes read |
26 // bytes read |
27 *len = ret; |
27 return ret; |
28 |
|
29 return SUCCESS; |
28 } |
30 } |
29 |
31 |
30 /* |
32 /* |
31 * Our sock_stream_methods.write method |
33 * Our sock_stream_methods.write method |
32 */ |
34 */ |
33 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t len) |
35 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len) |
34 { |
36 { |
35 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
37 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
36 int ret; |
38 int ret; |
37 |
39 |
38 // map directly to write(2) |
40 // map directly to write(2) |
39 if ((ret = write(sock->fd, buf, len)) < 0) |
41 if ((ret = write(sock->fd, buf, *len)) < 0) |
40 // errno |
42 // errno |
41 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE); |
43 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE); |
42 |
44 |
43 else |
45 // bytes read |
44 // bytes read |
46 *len = ret; |
45 return ret; |
47 |
|
48 return SUCCESS; |
|
49 } |
|
50 |
|
51 static err_t sock_tcp_event_init (struct sock_stream *base_sock) |
|
52 { |
|
53 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
|
54 |
|
55 return SUCCESS; |
|
56 } |
|
57 |
|
58 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask) |
|
59 { |
|
60 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
|
61 |
|
62 return SUCCESS; |
46 } |
63 } |
47 |
64 |
48 /* |
65 /* |
49 * Our sock_stream_type |
66 * Our sock_stream_type |
50 */ |
67 */ |
51 struct sock_stream_type sock_tcp_type = { |
68 struct sock_stream_type sock_tcp_type = { |
52 .methods.read = &sock_tcp_read, |
69 .methods.read = &sock_tcp_read, |
53 .methods.write = &sock_tcp_write, |
70 .methods.write = &sock_tcp_write, |
|
71 .methods.event_init = &sock_tcp_event_init, |
|
72 .methods.event_enable = &sock_tcp_event_enable, |
54 }; |
73 }; |
|
74 |
|
75 /* |
|
76 * Our basic socket event handler for driving our callbacks |
|
77 */ |
|
78 static void sock_tcp_event (evutil_socket_t fd, short what, void *arg) |
|
79 { |
|
80 struct sock_tcp *sock = arg; |
|
81 |
|
82 // invoke appropriate callback |
|
83 if (what & EV_READ && SOCK_TCP_BASE(sock)->cb_info->on_read) |
|
84 SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); |
|
85 |
|
86 if (what & EV_WRITE && SOCK_TCP_BASE(sock)->cb_info->on_write) |
|
87 SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); |
|
88 } |
55 |
89 |
56 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr) |
90 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr) |
57 { |
91 { |
58 // alloc |
92 // alloc |
59 if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL) |
93 if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL) |
135 |
182 |
136 // ok, done |
183 // ok, done |
137 return 0; |
184 return 0; |
138 } |
185 } |
139 |
186 |
|
187 err_t sock_tcp_set_nonblock (struct sock_tcp *sock, int nonblock) |
|
188 { |
|
189 // fcntl it |
|
190 // XXX: maintain old flags? |
|
191 if (fcntl(sock->fd, F_SETFL, nonblock ? O_NONBLOCK : 0) < 0) |
|
192 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_FCNTL); |
|
193 |
|
194 // ok |
|
195 return SUCCESS; |
|
196 } |
|
197 |
|
198 void sock_tcp_release (struct sock_tcp *sock) |
|
199 { |
|
200 // must not be connected |
|
201 assert(sock->fd < 0); |
|
202 |
|
203 // free |
|
204 free(sock); |
|
205 } |
|
206 |
140 err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err_info) |
207 err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err_info) |
141 { |
208 { |
142 struct sock_tcp *sock; |
209 struct sock_tcp *sock; |
143 err_t err; |
210 err_t err; |
144 |
211 |