16 static void sock_tcp_event_handler (evutil_socket_t fd, short what, void *arg) |
16 static void sock_tcp_event_handler (evutil_socket_t fd, short what, void *arg) |
17 { |
17 { |
18 struct sock_tcp *sock = arg; |
18 struct sock_tcp *sock = arg; |
19 |
19 |
20 // invoke appropriate callback |
20 // invoke appropriate callback |
21 if (what & EV_READ && SOCK_TCP_BASE(sock)->cb_info->on_read) |
21 sock_stream_invoke_callbacks(SOCK_TCP_BASE(sock), what); |
22 SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); |
|
23 |
|
24 if (what & EV_WRITE && SOCK_TCP_BASE(sock)->cb_info->on_write) |
|
25 SOCK_TCP_BASE(sock)->cb_info->on_read(SOCK_TCP_BASE(sock), SOCK_TCP_BASE(sock)->cb_arg); |
|
26 } |
22 } |
27 |
23 |
28 /* |
24 /* |
29 * Our sock_stream_methods.read method |
25 * Our sock_stream_methods.read method |
30 */ |
26 */ |
31 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len) |
27 static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len) |
32 { |
28 { |
33 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
29 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
34 int ret; |
30 int ret; |
35 |
31 |
36 // map directly to read(2) |
32 // read(), and detect non-EAGAIN or EOF |
37 if ((ret = read(sock->fd, buf, *len)) < 0) |
33 if ((ret = read(sock->fd, buf, *len)) < 0 && errno != EAGAIN) |
38 // errno |
34 // unexpected error |
39 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ); |
35 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ); |
40 |
36 |
41 // bytes read |
37 else if (ret == 0) |
42 *len = ret; |
38 // EOF |
43 |
39 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_READ_EOF); |
|
40 |
|
41 |
|
42 if (ret < 0) { |
|
43 // EAGAIN -> zero bytes |
|
44 *len = 0; |
|
45 |
|
46 } else { |
|
47 // normal -> bytes read |
|
48 *len = ret; |
|
49 } |
|
50 |
|
51 // ok |
44 return SUCCESS; |
52 return SUCCESS; |
45 } |
53 } |
46 |
54 |
47 /* |
55 /* |
48 * Our sock_stream_methods.write method |
56 * Our sock_stream_methods.write method |
50 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len) |
58 static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len) |
51 { |
59 { |
52 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
60 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
53 int ret; |
61 int ret; |
54 |
62 |
55 // map directly to write(2) |
63 // write(), and detect non-EAGAIN or EOF |
56 if ((ret = write(sock->fd, buf, *len)) < 0) |
64 if ((ret = write(sock->fd, buf, *len)) < 0 && errno != EAGAIN) |
57 // errno |
65 // unexpected error |
58 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE); |
66 RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE); |
59 |
67 |
60 // bytes read |
68 else if (ret == 0) |
61 *len = ret; |
69 // EOF |
|
70 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_WRITE_EOF); |
|
71 |
|
72 |
|
73 if (ret < 0) { |
|
74 // EAGAIN -> zero bytes |
|
75 *len = 0; |
|
76 |
|
77 } else { |
|
78 // normal -> bytes read |
|
79 *len = ret; |
|
80 } |
62 |
81 |
63 return SUCCESS; |
82 return SUCCESS; |
64 } |
83 } |
65 |
84 |
66 static err_t sock_tcp_event_init (struct sock_stream *base_sock) |
85 static err_t sock_tcp_event_init (struct sock_stream *base_sock) |
81 } |
100 } |
82 |
101 |
83 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask) |
102 static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask) |
84 { |
103 { |
85 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
104 struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp); |
86 |
105 |
|
106 // implemented in sock_tcp_add_event |
|
107 return sock_tcp_add_event(sock, mask); |
|
108 } |
|
109 |
|
110 /* |
|
111 * Our sock_stream_type |
|
112 */ |
|
113 struct sock_stream_type sock_tcp_type = { |
|
114 .methods.read = &sock_tcp_read, |
|
115 .methods.write = &sock_tcp_write, |
|
116 .methods.event_init = &sock_tcp_event_init, |
|
117 .methods.event_enable = &sock_tcp_event_enable, |
|
118 }; |
|
119 |
|
120 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr) |
|
121 { |
|
122 // alloc |
|
123 if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL) |
|
124 return ERR_CALLOC; |
|
125 |
|
126 // initialize base with sock_tcp_type |
|
127 sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type); |
|
128 |
|
129 // done |
|
130 return SUCCESS; |
|
131 } |
|
132 |
|
133 err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd) |
|
134 { |
|
135 // valid fd -XXX: err instead? |
|
136 assert(fd >= 0); |
|
137 |
|
138 // initialize |
|
139 sock->fd = fd; |
|
140 |
|
141 // done |
|
142 return SUCCESS; |
|
143 } |
|
144 |
|
145 err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg) |
|
146 { |
|
147 // require valid fd |
|
148 assert(sock->fd >= 0); |
|
149 |
|
150 // this is initialization |
|
151 assert(sock->ev_read == NULL && sock->ev_write == NULL); |
|
152 |
|
153 // create new event |
|
154 if ((sock->ev_read = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL) |
|
155 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW); |
|
156 |
|
157 if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL) |
|
158 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW); |
|
159 |
|
160 // ok |
|
161 return SUCCESS; |
|
162 } |
|
163 |
|
164 err_t sock_tcp_add_event (struct sock_tcp *sock, short mask) |
|
165 { |
87 // just add the appropraite events |
166 // just add the appropraite events |
88 if (mask & EV_READ && event_add(sock->ev_read, NULL)) |
167 if (mask & EV_READ && event_add(sock->ev_read, NULL)) |
89 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD); |
168 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD); |
90 |
169 |
91 if (mask & EV_WRITE && event_add(sock->ev_write, NULL)) |
170 if (mask & EV_WRITE && event_add(sock->ev_write, NULL)) |
92 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD); |
171 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD); |
93 |
172 |
94 // done |
173 // done |
95 return SUCCESS; |
|
96 } |
|
97 |
|
98 /* |
|
99 * Our sock_stream_type |
|
100 */ |
|
101 struct sock_stream_type sock_tcp_type = { |
|
102 .methods.read = &sock_tcp_read, |
|
103 .methods.write = &sock_tcp_write, |
|
104 .methods.event_init = &sock_tcp_event_init, |
|
105 .methods.event_enable = &sock_tcp_event_enable, |
|
106 }; |
|
107 |
|
108 err_t sock_tcp_alloc (struct sock_tcp **sock_ptr) |
|
109 { |
|
110 // alloc |
|
111 if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL) |
|
112 return ERR_CALLOC; |
|
113 |
|
114 // initialize base with sock_tcp_type |
|
115 sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type); |
|
116 |
|
117 // done |
|
118 return SUCCESS; |
|
119 } |
|
120 |
|
121 err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd) |
|
122 { |
|
123 // valid fd -XXX: err instead? |
|
124 assert(fd >= 0); |
|
125 |
|
126 // initialize |
|
127 sock->fd = fd; |
|
128 |
|
129 // done |
|
130 return SUCCESS; |
|
131 } |
|
132 |
|
133 err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg) |
|
134 { |
|
135 // require valid fd |
|
136 assert(sock->fd >= 0); |
|
137 |
|
138 // this is initialization |
|
139 assert(sock->ev_read == NULL && sock->ev_write == NULL); |
|
140 |
|
141 // create new event |
|
142 if ((sock->ev_read = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL) |
|
143 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW); |
|
144 |
|
145 if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL) |
|
146 return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW); |
|
147 |
|
148 // ok |
|
149 return SUCCESS; |
174 return SUCCESS; |
150 } |
175 } |
151 |
176 |
152 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service) |
177 err_t sock_tcp_init_connect (struct sock_tcp *sock, const char *hostname, const char *service) |
153 { |
178 { |