tsocket: move tsocket_simple_int_recv() to tsocket.c
[samba.git] / lib / tsocket / tsocket_helpers.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Stefan Metzmacher 2009
5
6      ** NOTE! The following LGPL license applies to the tevent
7      ** library. This does NOT imply that all of Samba is released
8      ** under the LGPL
9
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 3 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "replace.h"
25 #include "tsocket.h"
26 #include "tsocket_internal.h"
27
28 struct tdgram_sendto_queue_state {
29         /* this structs are owned by the caller */
30         struct {
31                 struct tevent_context *ev;
32                 struct tdgram_context *dgram;
33                 const uint8_t *buf;
34                 size_t len;
35                 const struct tsocket_address *dst;
36         } caller;
37         ssize_t ret;
38 };
39
40 static void tdgram_sendto_queue_trigger(struct tevent_req *req,
41                                          void *private_data);
42 static void tdgram_sendto_queue_done(struct tevent_req *subreq);
43
44 /**
45  * @brief Queue a dgram blob for sending through the socket
46  * @param[in] mem_ctx   The memory context for the result
47  * @param[in] ev        The event context the operation should work on
48  * @param[in] dgram     The tdgram_context to send the message buffer
49  * @param[in] queue     The existing dgram queue
50  * @param[in] buf       The message buffer
51  * @param[in] len       The message length
52  * @param[in] dst       The destination socket address
53  * @retval              The async request handle
54  *
55  * This function queues a blob for sending to destination through an existing
56  * dgram socket. The async callback is triggered when the whole blob is
57  * delivered to the underlying system socket.
58  *
59  * The caller needs to make sure that all non-scalar input parameters hang
60  * arround for the whole lifetime of the request.
61  */
62 struct tevent_req *tdgram_sendto_queue_send(TALLOC_CTX *mem_ctx,
63                                             struct tevent_context *ev,
64                                             struct tdgram_context *dgram,
65                                             struct tevent_queue *queue,
66                                             const uint8_t *buf,
67                                             size_t len,
68                                             struct tsocket_address *dst)
69 {
70         struct tevent_req *req;
71         struct tdgram_sendto_queue_state *state;
72         bool ok;
73
74         req = tevent_req_create(mem_ctx, &state,
75                                 struct tdgram_sendto_queue_state);
76         if (!req) {
77                 return NULL;
78         }
79
80         state->caller.ev        = ev;
81         state->caller.dgram     = dgram;
82         state->caller.buf       = buf;
83         state->caller.len       = len;
84         state->caller.dst       = dst;
85         state->ret              = -1;
86
87         ok = tevent_queue_add(queue,
88                               ev,
89                               req,
90                               tdgram_sendto_queue_trigger,
91                               NULL);
92         if (!ok) {
93                 tevent_req_nomem(NULL, req);
94                 goto post;
95         }
96
97         return req;
98
99  post:
100         tevent_req_post(req, ev);
101         return req;
102 }
103
104 static void tdgram_sendto_queue_trigger(struct tevent_req *req,
105                                          void *private_data)
106 {
107         struct tdgram_sendto_queue_state *state = tevent_req_data(req,
108                                         struct tdgram_sendto_queue_state);
109         struct tevent_req *subreq;
110
111         subreq = tdgram_sendto_send(state,
112                                     state->caller.ev,
113                                     state->caller.dgram,
114                                     state->caller.buf,
115                                     state->caller.len,
116                                     state->caller.dst);
117         if (tevent_req_nomem(subreq, req)) {
118                 return;
119         }
120         tevent_req_set_callback(subreq, tdgram_sendto_queue_done, req);
121 }
122
123 static void tdgram_sendto_queue_done(struct tevent_req *subreq)
124 {
125         struct tevent_req *req = tevent_req_callback_data(subreq,
126                                  struct tevent_req);
127         struct tdgram_sendto_queue_state *state = tevent_req_data(req,
128                                         struct tdgram_sendto_queue_state);
129         ssize_t ret;
130         int sys_errno;
131
132         ret = tdgram_sendto_recv(subreq, &sys_errno);
133         talloc_free(subreq);
134         if (ret == -1) {
135                 tevent_req_error(req, sys_errno);
136                 return;
137         }
138         state->ret = ret;
139
140         tevent_req_done(req);
141 }
142
143 ssize_t tdgram_sendto_queue_recv(struct tevent_req *req, int *perrno)
144 {
145         struct tdgram_sendto_queue_state *state = tevent_req_data(req,
146                                         struct tdgram_sendto_queue_state);
147         ssize_t ret;
148
149         ret = tsocket_simple_int_recv(req, perrno);
150         if (ret == 0) {
151                 ret = state->ret;
152         }
153
154         tevent_req_received(req);
155         return ret;
156 }
157