4 Copyright (C) Amitay Isaacs 2015
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
25 #include "common/pkt_read.c"
27 static void writer(int fd)
29 uint8_t buf[1024*1024];
31 size_t pkt_size[4] = { 100, 500, 1024, 1024*1024 };
35 for (i=0; i<1024*1024; i++) {
39 for (i=0; i<1000; i++) {
42 memcpy(buf, &buflen, sizeof(buflen));
44 ret = write(fd, buf, buflen);
46 printf("write error: %s\n", strerror(errno));
56 struct tevent_context *ev;
59 struct tevent_req *subreq;
62 static ssize_t reader_more(uint8_t *buf, size_t buflen, void *private_data);
63 static void reader_done(struct tevent_req *subreq);
65 static struct tevent_req *reader_send(TALLOC_CTX *mem_ctx,
66 struct tevent_context *ev,
69 struct tevent_req *req, *subreq;
70 struct reader_state *state;
72 req = tevent_req_create(mem_ctx, &state, struct reader_state);
80 subreq = pkt_read_send(state, state->ev, state->fd, 4,
81 state->buf, 1024, reader_more, NULL);
82 if (tevent_req_nomem(subreq, req)) {
83 tevent_req_post(req, ev);
86 state->subreq = subreq;
87 tevent_req_set_callback(subreq, reader_done, req);
91 static ssize_t reader_more(uint8_t *buf, size_t buflen, void *private_data)
95 if (buflen < sizeof(pkt_len)) {
96 return sizeof(pkt_len) - buflen;
99 pkt_len = *(uint32_t *)buf;
100 return pkt_len - buflen;
103 static void reader_done(struct tevent_req *subreq)
105 struct tevent_req *req = tevent_req_callback_data(
106 subreq, struct tevent_req);
107 struct reader_state *state = tevent_req_data(
108 req, struct reader_state);
114 nread = pkt_read_recv(subreq, state, &buf, &free_buf, &err);
116 state->subreq = NULL;
119 tevent_req_done(req);
121 tevent_req_error(req, err);
130 subreq = pkt_read_send(state, state->ev, state->fd, 4,
131 state->buf, 1024, reader_more, NULL);
132 if (tevent_req_nomem(subreq, req)) {
136 state->subreq = subreq;
137 tevent_req_set_callback(subreq, reader_done, req);
140 static void reader_recv(struct tevent_req *req, int *perr)
142 struct reader_state *state = tevent_req_data(
143 req, struct reader_state);
146 if (state->subreq != NULL) {
150 if (tevent_req_is_unix_error(req, &err)) {
158 static void reader_handler(struct tevent_context *ev, struct tevent_fd *fde,
159 uint16_t flags, void *private_data)
161 struct tevent_req *req = talloc_get_type_abort(
162 private_data, struct tevent_req);
163 struct reader_state *state = tevent_req_data(
164 req, struct reader_state);
166 assert(state->subreq != NULL);
167 pkt_read_handler(ev, fde, flags, state->subreq);
170 static void reader(int fd)
173 struct tevent_context *ev;
174 struct tevent_fd *fde;
175 struct tevent_req *req;
178 mem_ctx = talloc_new(NULL);
179 assert(mem_ctx != NULL);
181 ev = tevent_context_init(mem_ctx);
184 req = reader_send(mem_ctx, ev, fd);
187 fde = tevent_add_fd(ev, mem_ctx, fd, TEVENT_FD_READ,
188 reader_handler, req);
191 tevent_req_poll(req, ev);
193 reader_recv(req, &err);
198 talloc_free(mem_ctx);
201 static bool set_nonblocking(int fd)
205 v = fcntl(fd, F_GETFL, 0);
209 if (fcntl(fd, F_SETFL, v | O_NONBLOCK) == -1) {
235 if (!set_nonblocking(fd[0])) {