• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_UIO_PLT
18 
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "bsl_binlog_id.h"
22 #include "bsl_log_internal.h"
23 #include "bsl_log.h"
24 #include "bsl_err_internal.h"
25 #include "bsl_errno.h"
26 #include "bsl_uio.h"
27 #include "uio_base.h"
28 #include "uio_abstraction.h"
29 
BSL_UIO_NewMethod(void)30 BSL_UIO_Method *BSL_UIO_NewMethod(void)
31 {
32     BSL_UIO_Method *meth = (BSL_UIO_Method *)BSL_SAL_Calloc(1u, sizeof(BSL_UIO_Method));
33     if (meth == NULL) {
34         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05058, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
35             "new method is NULL.", NULL, NULL, NULL, NULL);
36         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
37         return NULL;
38     }
39 
40     return meth;
41 }
42 
BSL_UIO_FreeMethod(BSL_UIO_Method * meth)43 void BSL_UIO_FreeMethod(BSL_UIO_Method *meth)
44 {
45     BSL_SAL_FREE(meth);
46 }
47 
BSL_UIO_SetMethodType(BSL_UIO_Method * meth,int32_t type)48 int32_t BSL_UIO_SetMethodType(BSL_UIO_Method *meth, int32_t type)
49 {
50     if (meth == NULL) {
51         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
52         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05059, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
53             "set method type is NULL.", NULL, NULL, NULL, NULL);
54         return BSL_NULL_INPUT;
55     }
56     meth->uioType = type;
57     return BSL_SUCCESS;
58 }
59 
BSL_UIO_SetMethod(BSL_UIO_Method * meth,int32_t type,void * func)60 int32_t BSL_UIO_SetMethod(BSL_UIO_Method *meth, int32_t type, void *func)
61 {
62     if (meth == NULL || func == NULL) {
63         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
64         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05060, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
65             "set method is NULL.", NULL, NULL, NULL, NULL);
66         return BSL_NULL_INPUT;
67     }
68 
69     switch (type) {
70         case BSL_UIO_WRITE_CB:
71             meth->uioWrite = func;
72             break;
73         case BSL_UIO_READ_CB:
74             meth->uioRead = func;
75             break;
76         case BSL_UIO_CTRL_CB:
77             meth->uioCtrl = func;
78             break;
79         case BSL_UIO_CREATE_CB:
80             meth->uioCreate = func;
81             break;
82         case BSL_UIO_DESTROY_CB:
83             meth->uioDestroy = func;
84             break;
85         case BSL_UIO_PUTS_CB:
86             meth->uioPuts = func;
87             break;
88         case BSL_UIO_GETS_CB:
89             meth->uioGets = func;
90             break;
91         default:
92             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05025, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
93                 "method type is wrong.", NULL, NULL, NULL, NULL);
94             BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
95             return BSL_INVALID_ARG;
96     }
97     return BSL_SUCCESS;
98 }
99 
BSL_UIO_New(const BSL_UIO_Method * method)100 BSL_UIO *BSL_UIO_New(const BSL_UIO_Method *method)
101 {
102     int32_t ret = BSL_SUCCESS;
103     if (method == NULL) {
104         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
105         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05021, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
106             "method is NULL.", 0, 0, 0, 0);
107         return NULL;
108     }
109 
110     BSL_UIO *uio = (BSL_UIO *)BSL_SAL_Calloc(1, sizeof(struct UIO_ControlBlock));
111     if (uio == NULL) {
112         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
113         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05022, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
114             "uio malloc fail.", 0, 0, 0, 0);
115         return NULL;
116     }
117 
118     (void)memcpy_s(&uio->method, sizeof(BSL_UIO_Method), method, sizeof(BSL_UIO_Method));
119 
120     BSL_SAL_ReferencesInit(&(uio->references));
121     BSL_UIO_SetIsUnderlyingClosedByUio(uio, false);
122 
123     if (uio->method.uioCreate != NULL) {
124         ret = uio->method.uioCreate(uio);
125         if (ret != BSL_SUCCESS) {
126             BSL_ERR_PUSH_ERROR(BSL_UIO_FAIL);
127             BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05023, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
128                 "uio create data fail.", 0, 0, 0, 0);
129             BSL_SAL_FREE(uio);
130             return NULL;
131         }
132     }
133 
134     return uio;
135 }
136 
BSL_UIO_UpRef(BSL_UIO * uio)137 int32_t BSL_UIO_UpRef(BSL_UIO *uio)
138 {
139     if (uio == NULL) {
140         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05024, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
141             "uio is NULL.", 0, 0, 0, 0);
142         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
143         return BSL_INTERNAL_EXCEPTION;
144     }
145     if (uio->references.count == INT32_MAX) {
146         BSL_ERR_PUSH_ERROR(BSL_UIO_REF_MAX);
147         return BSL_UIO_REF_MAX;
148     }
149     int val = 0;
150     BSL_SAL_AtomicUpReferences(&(uio->references), &val);
151     return BSL_SUCCESS;
152 }
153 
BSL_UIO_Free(BSL_UIO * uio)154 void BSL_UIO_Free(BSL_UIO *uio)
155 {
156     if (uio == NULL) {
157         return;
158     }
159     int ret = 0;
160     BSL_SAL_AtomicDownReferences(&(uio->references), &ret);
161     if (ret > 0) {
162         return;
163     }
164     if (uio->userData != NULL && uio->userDataFreeFunc != NULL) {
165         (void)uio->userDataFreeFunc(uio->userData);
166         uio->userData = NULL;
167     }
168     if (uio->method.uioDestroy != NULL) {
169         (void)uio->method.uioDestroy(uio);
170     }
171     BSL_SAL_ReferencesFree(&(uio->references));
172     BSL_SAL_FREE(uio);
173     return;
174 }
175 
BSL_UIO_Write(BSL_UIO * uio,const void * data,uint32_t len,uint32_t * writeLen)176 int32_t BSL_UIO_Write(BSL_UIO *uio, const void *data, uint32_t len, uint32_t *writeLen)
177 {
178     if (uio == NULL || uio->method.uioWrite == NULL || data == NULL || writeLen == NULL || len == 0) {
179         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05026, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
180             "uio write: internal input error.", 0, 0, 0, 0);
181         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
182         return BSL_INTERNAL_EXCEPTION;   // if the uio is null, the send size is zero, means no data send;
183     }
184 
185     if (uio->init != 1) {
186         BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
187         return BSL_UIO_UNINITIALIZED;
188     }
189 
190     int32_t ret = uio->method.uioWrite(uio, data, len, writeLen);
191     if (ret == BSL_SUCCESS) {
192         uio->writeNum += (int64_t)*writeLen;
193     }
194 
195     return ret;
196 }
197 
BSL_UIO_Puts(BSL_UIO * uio,const char * buf,uint32_t * writeLen)198 int32_t BSL_UIO_Puts(BSL_UIO *uio, const char *buf, uint32_t *writeLen)
199 {
200     if (uio == NULL || uio->method.uioPuts == NULL || writeLen == NULL || buf == NULL) {
201         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
202         return BSL_INTERNAL_EXCEPTION;
203     }
204 
205     if (uio->init != 1) {
206         BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
207         return BSL_UIO_UNINITIALIZED;
208     }
209 
210     int32_t ret = uio->method.uioPuts(uio, buf, writeLen);
211     if (ret == BSL_SUCCESS) {
212         uio->writeNum += (int64_t)*writeLen;
213     }
214 
215     return ret;
216 }
217 
BSL_UIO_Gets(BSL_UIO * uio,char * buf,uint32_t * readLen)218 int32_t BSL_UIO_Gets(BSL_UIO *uio, char *buf, uint32_t *readLen)
219 {
220     if (uio == NULL || uio->method.uioGets == NULL || readLen == NULL || buf == NULL) {
221         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
222         return BSL_INTERNAL_EXCEPTION;
223     }
224 
225     if (uio->init != 1) {
226         BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
227         return BSL_UIO_UNINITIALIZED;
228     }
229 
230     int32_t ret = uio->method.uioGets(uio, buf, readLen);
231     if (ret == BSL_SUCCESS) {
232         uio->readNum += (int64_t)*readLen;
233     }
234 
235     return ret;
236 }
237 
BSL_UIO_Read(BSL_UIO * uio,void * data,uint32_t len,uint32_t * readLen)238 int32_t BSL_UIO_Read(BSL_UIO *uio, void *data, uint32_t len, uint32_t *readLen)
239 {
240     if (uio == NULL || uio->method.uioRead == NULL || data == NULL || len == 0 || readLen == NULL) {
241         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05027, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
242             "uio read: internal input error.", 0, 0, 0, 0);
243         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
244         return BSL_INTERNAL_EXCEPTION;
245     }
246 
247     if (uio->init != 1) {
248         BSL_ERR_PUSH_ERROR(BSL_UIO_UNINITIALIZED);
249         return BSL_UIO_UNINITIALIZED;
250     }
251 
252     int32_t ret = uio->method.uioRead(uio, data, len, readLen);
253     if (ret == BSL_SUCCESS) {
254         uio->readNum += (int64_t)*readLen;
255     }
256 
257     return ret;
258 }
259 
BSL_UIO_GetTransportType(const BSL_UIO * uio)260 int32_t BSL_UIO_GetTransportType(const BSL_UIO *uio)
261 {
262     if (uio == NULL) {
263         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05028, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
264             "uio is NULL.", 0, 0, 0, 0);
265         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
266         return BSL_NULL_INPUT;
267     }
268     return uio->method.uioType;
269 }
270 
BSL_UIO_GetUioChainTransportType(BSL_UIO * uio,const BSL_UIO_TransportType uioType)271 bool BSL_UIO_GetUioChainTransportType(BSL_UIO *uio, const BSL_UIO_TransportType uioType)
272 {
273     if (uio == NULL) {
274         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
275             "get uio type is NULL.", NULL, NULL, NULL, NULL);
276         return false;
277     }
278 
279     while (uio != NULL) {
280         if (BSL_UIO_GetTransportType(uio) == (int32_t)uioType) {
281             return true;
282         }
283         uio = BSL_UIO_Next(uio);
284     }
285     return false;
286 }
287 
BSL_UIO_SetUserData(BSL_UIO * uio,void * data)288 int32_t BSL_UIO_SetUserData(BSL_UIO *uio, void *data)
289 {
290     if (uio == NULL) {
291         BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05029, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN, "uio is NULL.", 0, 0, 0, 0);
292         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
293         return BSL_NULL_INPUT;
294     }
295 
296     uio->userData = data;
297     return BSL_SUCCESS;
298 }
299 
BSL_UIO_SetUserDataFreeFunc(BSL_UIO * uio,BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc)300 int32_t BSL_UIO_SetUserDataFreeFunc(BSL_UIO *uio, BSL_UIO_USERDATA_FREE_FUNC userDataFreeFunc)
301 {
302     if (uio == NULL) {
303         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
304         return BSL_NULL_INPUT;
305     }
306     uio->userDataFreeFunc = userDataFreeFunc;
307     return BSL_SUCCESS;
308 }
309 
BSL_UIO_GetUserData(const BSL_UIO * uio)310 void *BSL_UIO_GetUserData(const BSL_UIO *uio)
311 {
312     if (uio == NULL) {
313         return NULL;
314     }
315 
316     return uio->userData;
317 }
318 
BSL_UIO_GetIsUnderlyingClosedByUio(const BSL_UIO * uio)319 bool BSL_UIO_GetIsUnderlyingClosedByUio(const BSL_UIO *uio)
320 {
321     if (uio == NULL) {
322         return false; // If the value is empty, the function will not release the value.
323     }
324     return uio->isUnderlyingClosedByUio;
325 }
326 
BSL_UIO_SetIsUnderlyingClosedByUio(BSL_UIO * uio,bool close)327 void BSL_UIO_SetIsUnderlyingClosedByUio(BSL_UIO *uio, bool close)
328 {
329     if (uio == NULL) {
330         return;
331     }
332     uio->isUnderlyingClosedByUio = close;
333 }
334 
BSL_UIO_GetMethod(const BSL_UIO * uio)335 const BSL_UIO_Method *BSL_UIO_GetMethod(const BSL_UIO *uio)
336 {
337     if (uio == NULL) {
338         return NULL;
339     }
340     return &uio->method;
341 }
342 
UIO_GetInit(BSL_UIO * uio,int32_t larg,bool * parg)343 static int32_t UIO_GetInit(BSL_UIO *uio, int32_t larg, bool *parg)
344 {
345     if (larg != (int32_t)sizeof(bool) || parg == NULL) {
346         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
347         return BSL_INVALID_ARG;
348     }
349     *parg = uio->init;
350     return BSL_SUCCESS;
351 }
352 
UIO_GetReadNum(BSL_UIO * uio,int32_t larg,int64_t * parg)353 static int32_t UIO_GetReadNum(BSL_UIO *uio, int32_t larg, int64_t *parg)
354 {
355     if (larg != (int32_t)sizeof(int64_t) || parg == NULL) {
356         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
357         return BSL_INVALID_ARG;
358     }
359     *parg = uio->readNum;
360     return BSL_SUCCESS;
361 }
362 
UIO_GetWriteNum(BSL_UIO * uio,int32_t larg,int64_t * parg)363 static int32_t UIO_GetWriteNum(BSL_UIO *uio, int32_t larg, int64_t *parg)
364 {
365     if (larg != (int32_t)sizeof(int64_t) || parg == NULL) {
366         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
367         return BSL_INVALID_ARG;
368     }
369     *parg = uio->writeNum;
370     return BSL_SUCCESS;
371 }
372 
BSL_UIO_Ctrl(BSL_UIO * uio,int32_t cmd,int32_t larg,void * parg)373 int32_t BSL_UIO_Ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg, void *parg)
374 {
375     if (uio == NULL || uio->method.uioCtrl == NULL) {
376         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
377         return BSL_NULL_INPUT;
378     }
379     switch (cmd) {
380         case BSL_UIO_GET_INIT:
381             return UIO_GetInit(uio, larg, parg);
382         case BSL_UIO_GET_READ_NUM:
383             return UIO_GetReadNum(uio, larg, parg);
384         case BSL_UIO_GET_WRITE_NUM:
385             return UIO_GetWriteNum(uio, larg, parg);
386         default:
387             return uio->method.uioCtrl(uio, cmd, larg, parg);
388     }
389 }
390 
BSL_UIO_GetCtx(const BSL_UIO * uio)391 void *BSL_UIO_GetCtx(const BSL_UIO *uio)
392 {
393     if (uio == NULL) {
394         return NULL;
395     }
396     return uio->ctx;
397 }
398 
BSL_UIO_SetCtx(BSL_UIO * uio,void * ctx)399 void BSL_UIO_SetCtx(BSL_UIO *uio, void *ctx)
400 {
401     if (uio != NULL) {
402         uio->ctx = ctx;
403     }
404 }
405 
BSL_UIO_GetFd(BSL_UIO * uio)406 int32_t BSL_UIO_GetFd(BSL_UIO *uio)
407 {
408     int32_t fd = -1;
409     (void)BSL_UIO_Ctrl(uio, BSL_UIO_GET_FD, (int32_t)sizeof(fd), &fd); // Parameters are checked by each ctrl function.
410     return fd;
411 }
412 
BSL_UIO_SetFD(BSL_UIO * uio,int fd)413 void BSL_UIO_SetFD(BSL_UIO *uio, int fd)
414 {
415     bool invalid = (uio == NULL) || (fd < 0);
416     if (invalid) {
417         return;
418     }
419     BSL_UIO_Ctrl(uio, BSL_UIO_SET_FD, (int32_t)sizeof(fd), &fd);
420 }
421 
BSL_UIO_SetFlags(BSL_UIO * uio,uint32_t flags)422 int32_t BSL_UIO_SetFlags(BSL_UIO *uio, uint32_t flags)
423 {
424     if (uio == NULL) {
425         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
426         return BSL_NULL_INPUT;
427     }
428     uint32_t validFlags =
429         BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY | BSL_UIO_FLAGS_BASE64_NO_NEWLINE | BSL_UIO_FLAGS_BASE64_PEM;
430     if ((flags & validFlags) == 0 || flags > validFlags) {
431         BSL_ERR_PUSH_ERROR(BSL_INVALID_ARG);
432         return BSL_INVALID_ARG;
433     }
434 
435     uio->flags |= flags;
436     return BSL_SUCCESS;
437 }
438 
BSL_UIO_ClearFlags(BSL_UIO * uio,uint32_t flags)439 int32_t BSL_UIO_ClearFlags(BSL_UIO *uio, uint32_t flags)
440 {
441     if (uio == NULL) {
442         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
443         return BSL_NULL_INPUT;
444     }
445     uio->flags &= ~flags;
446     return BSL_SUCCESS;
447 }
448 
BSL_UIO_TestFlags(const BSL_UIO * uio,uint32_t flags,uint32_t * out)449 uint32_t BSL_UIO_TestFlags(const BSL_UIO *uio, uint32_t flags, uint32_t *out)
450 {
451     if (uio == NULL || out == NULL) {
452         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
453         return BSL_NULL_INPUT;
454     }
455     *out = uio->flags & flags;
456     return BSL_SUCCESS;
457 }
458 
BSL_UIO_SetInit(BSL_UIO * uio,bool init)459 void BSL_UIO_SetInit(BSL_UIO *uio, bool init)
460 {
461     if (uio != NULL) {
462         uio->init = init;
463     }
464 }
465 
466 /**
467  * @brief   Checking for Fatal I/O Errors
468  *
469  * @param   err [IN] error type
470  *
471  * @return  true :Fatal error
472  *          false:No fatal errors
473  */
UioIsNonFatalErr(int32_t err)474 bool UioIsNonFatalErr(int32_t err)
475 {
476     bool ret = true;
477     /** @alias Check whether err is a fatal error and modify ret. */
478     switch (err) {
479 #if defined(ENOTCONN)
480         case ENOTCONN:
481 #endif
482 
483 #ifdef EINTR
484         case EINTR:
485 #endif
486 
487 #ifdef EINPROGRESS
488         case EINPROGRESS:
489 #endif
490 
491 #ifdef EWOULDBLOCK
492 #if !defined(WSAEWOULDBLOCK) || WSAEWOULDBLOCK != EWOULDBLOCK
493         case EWOULDBLOCK:
494 #endif
495 #endif
496 
497 #ifdef EAGAIN
498 #if EWOULDBLOCK != EAGAIN
499         case EAGAIN:
500 #endif
501 #endif
502 
503 #ifdef EALREADY
504         case EALREADY:
505 #endif
506 
507 #ifdef EPROTO
508         case EPROTO:
509 #endif
510             ret = true;
511             break;
512         default:
513             ret = false;
514             break;
515     }
516     return ret;
517 }
518 
BSL_UIO_Append(BSL_UIO * uio,BSL_UIO * tail)519 int32_t BSL_UIO_Append(BSL_UIO *uio, BSL_UIO *tail)
520 {
521     bool invalid = (uio == NULL) || (tail == NULL);
522     if (invalid) {
523         BSL_ERR_PUSH_ERROR(BSL_NULL_INPUT);
524         return BSL_NULL_INPUT;
525     }
526     BSL_UIO *t = uio;
527     while (t->next != NULL) {
528         t = t->next;
529     }
530     t->next = tail;
531     tail->prev = t;
532     return BSL_SUCCESS;
533 }
534 
BSL_UIO_PopCurrent(BSL_UIO * uio)535 BSL_UIO *BSL_UIO_PopCurrent(BSL_UIO *uio)
536 {
537     if (uio == NULL) {
538         return NULL;
539     }
540     BSL_UIO *ret = uio->next;
541     if (uio->prev != NULL) {
542         uio->prev->next = uio->next;
543     }
544     if (uio->next != NULL) {
545         uio->next->prev = uio->prev;
546     }
547     uio->prev = NULL;
548     uio->next = NULL;
549     return ret;
550 }
551 
BSL_UIO_FreeChain(BSL_UIO * uio)552 void BSL_UIO_FreeChain(BSL_UIO *uio)
553 {
554     BSL_UIO *b = uio;
555     while (b != NULL) {
556         int ref = b->references.count;
557         BSL_UIO *next = b->next;
558         BSL_UIO_Free(b);
559         if (ref > 1) {
560             break;
561         }
562         b = next;
563     }
564 }
565 
BSL_UIO_Next(BSL_UIO * uio)566 BSL_UIO *BSL_UIO_Next(BSL_UIO *uio)
567 {
568     if (uio == NULL) {
569         return NULL;
570     }
571     return uio->next;
572 }
573 
574 #endif /* HITLS_BSL_UIO_PLT */
575