1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * Contains helper routines dealing with syncronous access to a non-blocking
19 * sokets.
20 */
21
22 #ifndef ANDROID_SYNC_UTILS_H
23 #define ANDROID_SYNC_UTILS_H
24
25 #include "android/android.h"
26 #include "sockets.h"
27
28 /* Descriptor for a connected non-blocking socket providing synchronous I/O */
29 typedef struct SyncSocket SyncSocket;
30
31 /*
32 * Connect to a non-blocking socket for further synchronous I/O.
33 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
34 * to this routine.
35 * Param:
36 * fd - File descriptor for the socket, created with socket_create_xxx routine.
37 * sockaddr - Address of the socket to connect to.
38 * timeout - Time out (in milliseconds) to wait for the connection to occur.
39 * Return:
40 * Initialized SyncSocket descriptor on success, or NULL on failure.
41 */
42 SyncSocket* syncsocket_connect(int fd, SockAddress* sockaddr, int timeout);
43
44 /*
45 * Initializes a non-blocking socket for further synchronous I/O.
46 * Note: this routine will explicitly call socket_set_nonblock on the fd passed
47 * to this routine.
48 * Param:
49 * fd - File descriptor for the already connected socket.
50 * Return:
51 * Initialized SyncSocket descriptor on success, or NULL on failure.
52 */
53 SyncSocket* syncsocket_init(int fd);
54
55 /*
56 * Closes SyncSocket descriptor obtained from syncsocket_connect routine.
57 * Param:
58 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
59 */
60 void syncsocket_close(SyncSocket* ssocket);
61
62 /*
63 * Frees memory allocated for SyncSocket descriptor obtained from
64 * syncsocket_connect routine. Note that this routine will also close socket
65 * connection.
66 * Param:
67 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
68 */
69 void syncsocket_free(SyncSocket* ssocket);
70
71 /*
72 * Prepares the socket for read.
73 * Note: this routine must be called before calling into syncsocket_read_xxx
74 * routines.
75 * Param:
76 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
77 * Return:
78 * 0 on success, or -1 on failure.
79 */
80 int syncsocket_start_read(SyncSocket* ssocket);
81
82 /*
83 * Clears the socket after reading.
84 * Note: this routine must be called after all expected data has been read from
85 * the socket.
86 * Param:
87 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
88 * Return:
89 * 0 on success, or -1 on failure.
90 */
91 int syncsocket_stop_read(SyncSocket* ssocket);
92
93 /*
94 * Prepares the socket for write.
95 * Note: this routine must be called before calling into syncsocket_write_xxx
96 * routines.
97 * Param:
98 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
99 * Return:
100 * 0 on success, or -1 on failure.
101 */
102 int syncsocket_start_write(SyncSocket* ssocket);
103
104 /*
105 * Clears the socket after writing.
106 * Note: this routine must be called after all data has been written to the
107 * socket.
108 * Param:
109 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
110 * Return:
111 * 0 on success, or -1 on failure.
112 */
113 int syncsocket_stop_write(SyncSocket* ssocket);
114
115 /*
116 * Synchronously reads from the socket.
117 * Note: syncsocket_start_read must be called before first call to this routine.
118 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
119 * be called to read all necessary data from the socket. When all necessary data
120 * has been read, syncsocket_stop_read must be called.
121 * Param:
122 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
123 * buf - Buffer where to read data.
124 * size - Number of bytes to read.
125 * deadline - Absoulte deadline time to complete the reading.
126 * Return:
127 * Number of bytes read on success, or -1 on failure.
128 */
129 ssize_t syncsocket_read_absolute(SyncSocket* ssocket,
130 void* buf,
131 size_t size,
132 int64_t deadline);
133
134 /*
135 * Synchronously reads from the socket.
136 * Note: syncsocket_start_read must be called before first call to this routine.
137 * Once syncsocket_start_read has been called, multiple syncsocket_read_xxx can
138 * be called to read all necessary data from the socket. When all necessary data
139 * has been read, syncsocket_stop_read must be called.
140 * Param:
141 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
142 * buf - Buffer where to read data.
143 * size - Number of bytes to read.
144 * timeout - Timeout (in milliseconds) to complete the reading.
145 * Return:
146 * Number of bytes read on success, or -1 on failure.
147 */
148 ssize_t syncsocket_read(SyncSocket* ssocket, void* buf, size_t size, int timeout);
149
150 /*
151 * Synchronously writes to the socket.
152 * Note: syncsocket_start_write must be called before first call to this routine.
153 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
154 * be called to write all necessary data to the socket. When all necessary data
155 * has been written, syncsocket_stop_write must be called.
156 * Param:
157 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
158 * buf - Buffer containing data to write.
159 * size - Number of bytes to write.
160 * deadline - Absoulte deadline time to complete the writing.
161 * Return:
162 * Number of bytes written on success,or -1 on failure.
163 */
164 ssize_t syncsocket_write_absolute(SyncSocket* ssocket,
165 const void* buf,
166 size_t size,
167 int64_t deadline);
168
169 /*
170 * Synchronously writes to the socket.
171 * Note: syncsocket_start_write must be called before first call to this routine.
172 * Once syncsocket_start_write has been called, multiple syncsocket_write_xxx can
173 * be called to write all necessary data to the socket. When all necessary data
174 * has been written, syncsocket_stop_write must be called.
175 * Param:
176 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
177 * buf - Buffer containing data to write.
178 * size - Number of bytes to write.
179 * timeout - Timeout (in milliseconds) to complete the writing.
180 * Return:
181 * Number of bytes written on success, or -1 on failure.
182 */
183 ssize_t syncsocket_write(SyncSocket* ssocket,
184 const void* buf,
185 size_t size,
186 int timeout);
187
188 /*
189 * Synchronously reads a line terminated with '\n' from the socket.
190 * Note: syncsocket_start_read must be called before first call to this routine.
191 * Param:
192 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
193 * buffer - Buffer where to read line.
194 * size - Number of characters the buffer can contain.
195 * deadline - Absoulte deadline time to complete the reading.
196 * Return:
197 * Number of chracters read on success, 0 on deadline expiration,
198 * or -1 on failure.
199 */
200 ssize_t syncsocket_read_line_absolute(SyncSocket* ssocket,
201 char* buffer,
202 size_t size,
203 int64_t deadline);
204
205 /*
206 * Synchronously reads a line terminated with '\n' from the socket.
207 * Note: syncsocket_start_read must be called before first call to this routine.
208 * Param:
209 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
210 * buffer - Buffer where to read line.
211 * size - Number of characters the buffer can contain.
212 * timeout - Timeout (in milliseconds) to complete the reading.
213 * Return:
214 * Number of chracters read on success, 0 on deadline expiration,
215 * or -1 on failure.
216 */
217 ssize_t syncsocket_read_line(SyncSocket* ssocket,
218 char* buffer,
219 size_t size,
220 int timeout);
221
222 /* Gets socket descriptor associated with the sync socket.
223 * Param:
224 * ssocket - SyncSocket descriptor obtained from syncsocket_connect routine.
225 * Return
226 * Socket descriptor associated with the sync socket.
227 */
228 int syncsocket_get_socket(SyncSocket* ssocket);
229
230 /* Converts syncsocket_xxx operation status into success / failure result.
231 * Param:
232 * status - syncsocket_xxx operation status to convert.
233 * Return:
234 * 0 if status passed to this routine indicated a success, or < 0 if status
235 * indicated a failure.
236 */
237 static inline int
syncsocket_result(int status)238 syncsocket_result(int status)
239 {
240 if (status == 0) {
241 // Status 0 returned from syncsocket_xxx means "disconnection", which is
242 // a failure.
243 status = -1;
244 } else if (status > 0) {
245 // Status > 0 means success.
246 status = 0;
247 }
248 return status;
249 }
250
251 #endif // ANDROID_SYNC_UTILS_H
252