• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <fcntl.h>
32 #include <poll.h>
33 #include "securec.h"
34 #include "los_list.h"
35 #include "los_mux.h"
36 #include "los_sem.h"
37 #include "los_debug.h"
38 #include "los_memory.h"
39 #include "pipe_impl.h"
40 
41 #if (LOSCFG_POSIX_PIPE_API == 1)
42 
43 #define PIPE_DEV_NUM            32
44 #define PIPE_FD_NUM             (PIPE_DEV_NUM << 1)
45 #define PIPE_DEV_NAME_MAX       32
46 #define PIPE_DEV_FD_BITMAP_LEN  ((PIPE_FD_NUM >> 5) + 1)
47 #define PIPE_DEV_BUF_SIZE       1024
48 #define PIPE_READ               1
49 #define PIPE_WRITE              2
50 
51 #define PIPE_DEV_LOCK(mutex)    do {                            \
52     UINT32 __ret = LOS_MuxPend(mutex, LOS_WAIT_FOREVER);        \
53     if (__ret != LOS_OK) {                                      \
54         PRINT_ERR("pipe device lock error, ret = %x\n", __ret); \
55     }                                                           \
56 } while (0)
57 
58 #define PIPE_DEV_UNLOCK(mutex)    do {                            \
59     UINT32 __ret = LOS_MuxPost(mutex);                            \
60     if (__ret != LOS_OK) {                                        \
61         PRINT_ERR("pipe device unlock error, ret = %x\n", __ret); \
62     }                                                             \
63 } while (0)
64 
65 #define PIPE_RW_WAIT(sem)    do {                                           \
66     LosSemCB *__sem = GET_SEM(sem);                                         \
67     while (__sem->semCount != 0) {                                          \
68         UINT32 __ret = LOS_SemPend(__sem->semID, LOS_WAIT_FOREVER);         \
69         if (__ret != LOS_OK) {                                              \
70             PRINT_ERR("pipe device R/W sem wait error, ret = %x\n", __ret); \
71         }                                                                   \
72     }                                                                       \
73 } while (0)
74 
75 #define PIPE_RW_POST(sem)    do {                                           \
76     LosSemCB *__sem = GET_SEM(sem);                                         \
77     while (__sem->semCount == 0) {                                          \
78         UINT32 __ret = LOS_SemPost(__sem->semID);                           \
79         if (__ret != LOS_OK) {                                              \
80             PRINT_ERR("pipe device R/W sem post error, ret = %x\n", __ret); \
81         }                                                                   \
82     }                                                                       \
83 } while (0)
84 
85 struct PipeDev {
86     CHAR devName[PIPE_DEV_NAME_MAX];
87     UINT32 num;
88     UINT32 mutex;
89     LOS_DL_LIST list;
90     UINT32 readSem;
91     UINT32 writeSem;
92     UINT8 *ringBuffer;
93     size_t bufferSize;
94     size_t readIndex;
95     size_t writeIndex;
96     BOOL roll;
97     UINT32 readerCnt;
98     UINT32 writerCnt;
99     UINT32 ref;
100     struct PollWaitQueue wq;
101 };
102 
103 struct PipeFdDev {
104     struct PipeDev *dev;
105     BOOL openFlag;
106 };
107 
108 STATIC LOS_DL_LIST g_devList = {&g_devList, &g_devList};
109 STATIC UINT32 g_devListMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
110 
111 STATIC UINT32 g_devNumBitmap = 0;
112 STATIC UINT32 g_devFdBitmap[PIPE_DEV_FD_BITMAP_LEN] = {0};
113 STATIC struct PipeFdDev g_devFd[PIPE_FD_NUM] = {0};
114 STATIC UINT32 g_devFdMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
115 STATIC INT32 g_devStartFd = 0;
116 
PipeDevNumAlloc(VOID)117 STATIC INT32 PipeDevNumAlloc(VOID)
118 {
119     UINT32 temp = g_devNumBitmap;
120     INT32 devNum = 0;
121 
122     while (temp & 0x1) {
123         devNum++;
124         temp = temp >> 1;
125     }
126 
127     if (devNum >= PIPE_DEV_NUM) {
128         return -1;
129     }
130     g_devNumBitmap |= 1U << devNum;
131 
132     return devNum;
133 }
134 
PipeDevNumFree(INT32 devNum)135 STATIC VOID PipeDevNumFree(INT32 devNum)
136 {
137     if ((devNum < 0) || (devNum >= PIPE_DEV_NUM)) {
138         return;
139     }
140     g_devNumBitmap &= ~(1U << devNum);
141 }
142 
PipeDevFind(const CHAR * path)143 STATIC struct PipeDev *PipeDevFind(const CHAR *path)
144 {
145     struct PipeDev *dev = NULL;
146 
147     (VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
148     if (!LOS_ListEmpty(&g_devList)) {
149         LOS_DL_LIST_FOR_EACH_ENTRY(dev, &g_devList, struct PipeDev, list) {
150             if (!strncmp(dev->devName, path, PIPE_DEV_NAME_MAX)) {
151                 (VOID)LOS_MuxPost(g_devListMutex);
152                 return dev;
153             }
154         }
155     }
156     (VOID)LOS_MuxPost(g_devListMutex);
157     return NULL;
158 }
159 
PipeRingbufferRead(struct PipeDev * dev,VOID * buf,size_t len)160 STATIC size_t PipeRingbufferRead(struct PipeDev *dev, VOID *buf, size_t len)
161 {
162     size_t nbytes;
163 
164     if (dev->readIndex < dev->writeIndex) {
165         nbytes = dev->writeIndex - dev->readIndex;
166     } else if (dev->readIndex > dev->writeIndex) {
167         nbytes = dev->bufferSize - dev->readIndex;
168     } else {
169         if (dev->roll == FALSE) {
170             return 0;
171         } else {
172             nbytes = dev->bufferSize - dev->readIndex;
173         }
174     }
175     nbytes = (nbytes > len) ? len : nbytes;
176     (VOID)memcpy_s(buf, len, dev->ringBuffer + dev->readIndex, nbytes);
177     dev->readIndex += nbytes;
178     if (dev->readIndex >= dev->bufferSize) {
179         dev->readIndex = 0;
180         dev->roll = FALSE;
181     }
182 
183     return nbytes;
184 }
185 
PipeRingbufferWrite(struct PipeDev * dev,const VOID * buf,size_t len)186 STATIC size_t PipeRingbufferWrite(struct PipeDev *dev, const VOID *buf, size_t len)
187 {
188     size_t nbytes;
189 
190     if (dev->readIndex < dev->writeIndex) {
191         nbytes = dev->bufferSize - dev->writeIndex;
192     } else if (dev->readIndex > dev->writeIndex) {
193         nbytes = dev->readIndex - dev->writeIndex;
194     } else {
195         if (dev->roll == TRUE) {
196             return 0;
197         } else {
198             nbytes = dev->bufferSize - dev->writeIndex;
199         }
200     }
201 
202     nbytes = (nbytes > len) ? len : nbytes;
203     (VOID)memcpy_s(dev->ringBuffer + dev->writeIndex, dev->bufferSize
204                    - dev->writeIndex, buf, nbytes);
205     dev->writeIndex += nbytes;
206     if (dev->writeIndex >= dev->bufferSize) {
207         dev->roll = TRUE;
208         dev->writeIndex = 0;
209     }
210 
211     return nbytes;
212 }
213 
PipeDevRegister(CHAR * devName,UINT32 len)214 STATIC INT32 PipeDevRegister(CHAR *devName, UINT32 len)
215 {
216     INT32 ret;
217     INT32 num = PipeDevNumAlloc();
218     struct PipeDev *devTemp = NULL;
219     if (num < 0) {
220         return -ENODEV;
221     }
222 
223     struct PipeDev *dev = LOS_MemAlloc(OS_SYS_MEM_ADDR, sizeof(struct PipeDev));
224     if (dev == NULL) {
225         ret = -ENOMEM;
226         goto ERROR;
227     }
228     (VOID)memset_s(dev, sizeof(struct PipeDev), 0, sizeof(struct PipeDev));
229     (VOID)snprintf_s(dev->devName, PIPE_DEV_NAME_MAX, PIPE_DEV_NAME_MAX - 1, "%s%d", PIPE_DEV_PATH, num);
230     (VOID)memcpy_s(devName, len, dev->devName, strlen(dev->devName));
231 
232     devTemp = PipeDevFind(dev->devName);
233     if (devTemp != NULL) {
234         ret = -EEXIST;
235         goto ERROR;
236     }
237 
238     ret = LOS_MuxCreate(&dev->mutex);
239     if (ret != LOS_OK) {
240         ret = -ENOSPC;
241         goto ERROR;
242     }
243 
244     ret = LOS_SemCreate(0, &dev->readSem);
245     if (ret != LOS_OK) {
246         (VOID)LOS_MuxDelete(dev->mutex);
247         ret = -ENOSPC;
248         goto ERROR;
249     }
250 
251     ret = LOS_SemCreate(0, &dev->writeSem);
252     if (ret != LOS_OK) {
253         (VOID)LOS_MuxDelete(dev->mutex);
254         (VOID)LOS_SemDelete(dev->readSem);
255         ret = -ENOSPC;
256         goto ERROR;
257     }
258 
259     dev->num = num;
260     PollWaitQueueInit(&dev->wq);
261 
262     (VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
263     LOS_ListAdd(&g_devList, &dev->list);
264     (VOID)LOS_MuxPost(g_devListMutex);
265 
266     return 0;
267 ERROR:
268     if (dev != NULL) {
269         (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev);
270     }
271     PipeDevNumFree(num);
272     return ret;
273 }
274 
PipeDevUnregister(struct PipeDev * dev)275 STATIC INT32 PipeDevUnregister(struct PipeDev *dev)
276 {
277     BOOL findFlag = FALSE;
278 
279     (VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
280     if (LOS_ListEmpty(&g_devList)) {
281         (VOID)LOS_MuxPost(g_devListMutex);
282         return -ENODEV;
283     }
284 
285     struct PipeDev *tmpDev = NULL;
286     LOS_DL_LIST_FOR_EACH_ENTRY(tmpDev, &g_devList, struct PipeDev, list) {
287         if (tmpDev == dev) {
288             LOS_ListDelete(&dev->list);
289             findFlag = TRUE;
290             break;
291         }
292     }
293     (VOID)LOS_MuxPost(g_devListMutex);
294 
295     if (findFlag != TRUE) {
296         return -ENODEV;
297     }
298 
299     PipeDevNumFree(dev->num);
300     (VOID)LOS_MuxDelete(dev->mutex);
301     (VOID)LOS_SemDelete(dev->readSem);
302     (VOID)LOS_SemDelete(dev->writeSem);
303     (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev->ringBuffer);
304     dev->ringBuffer = NULL;
305     (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, dev);
306 
307     return 0;
308 }
309 
PipeDevFdAlloc(VOID)310 STATIC INT32 PipeDevFdAlloc(VOID)
311 {
312     UINT32 i = 0;
313     INT32 fd = 0;
314 
315     while (g_devFdBitmap[i] & (1U << fd)) {
316         fd++;
317         if (fd == 32) { /* 32: bit index max is 32. */
318             i++;
319             fd = 0;
320         }
321 
322         if (i == PIPE_DEV_FD_BITMAP_LEN) {
323             return -1;
324         }
325     }
326     g_devFdBitmap[i] |= (1U << fd);
327     return (fd + (i << 5)); /* 5: i is the multiple of 32. */
328 }
329 
PipeDevFdFree(INT32 fd)330 STATIC VOID PipeDevFdFree(INT32 fd)
331 {
332     g_devFdBitmap[fd >> 5] &= ~(1U << (fd & 0x1F)); /* 5: fd is the multiple of 32. */
333 }
334 
PipePollNotify(struct PipeDev * dev,PollEvent event)335 STATIC VOID PipePollNotify(struct PipeDev *dev, PollEvent event)
336 {
337     struct PollWaitQueue *waitQueue = &dev->wq;
338 
339     if (event & POLLERR) {
340         event &= ~(POLLIN | POLLOUT);
341     }
342 
343     PollNotify(waitQueue, event);
344 }
345 
PipeOpen(const CHAR * path,INT32 openFlag,INT32 minFd)346 INT32 PipeOpen(const CHAR *path, INT32 openFlag, INT32 minFd)
347 {
348     struct PipeDev *dev = NULL;
349     INT32 fd = -1;
350 
351     if (path == NULL) {
352         errno = EINVAL;
353         return -1;
354     }
355 
356     if ((openFlag != O_RDONLY) && (openFlag != O_WRONLY)) {
357         errno = EINVAL;
358         return -1;
359     }
360 
361     dev = PipeDevFind(path);
362     if (dev == NULL) {
363         errno = ENODEV;
364         return -1;
365     }
366 
367     fd = PipeDevFdAlloc();
368     if (fd < 0) {
369         errno = EBUSY;
370         return -1;
371     }
372 
373     (VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
374     g_devFd[fd].dev = dev;
375     g_devFd[fd].openFlag = openFlag;
376     g_devStartFd = minFd;
377     (VOID)LOS_MuxPost(g_devFdMutex);
378 
379     PIPE_DEV_LOCK(dev->mutex);
380     if (openFlag == O_RDONLY) {
381         dev->readerCnt++;
382     } else if (openFlag == O_WRONLY) {
383         dev->writerCnt++;
384     }
385     dev->ref++;
386 
387     if (dev->ringBuffer == NULL) {
388         dev->ringBuffer = LOS_MemAlloc(OS_SYS_MEM_ADDR, PIPE_DEV_BUF_SIZE);
389         if (dev->ringBuffer == NULL) {
390             PIPE_DEV_UNLOCK(dev->mutex);
391             PipeDevFdFree(fd);
392             errno = ENOMEM;
393             return -1;
394         }
395         dev->bufferSize = PIPE_DEV_BUF_SIZE;
396     }
397     PIPE_DEV_UNLOCK(dev->mutex);
398 
399     return (fd + minFd);
400 }
401 
PipeFdDevGet(INT32 fd)402 STATIC INLINE struct PipeFdDev *PipeFdDevGet(INT32 fd)
403 {
404     if (fd < g_devStartFd) {
405         return NULL;
406     }
407 
408     fd -= g_devStartFd;
409     if (fd >= PIPE_FD_NUM) {
410         return NULL;
411     }
412     return &g_devFd[fd];
413 }
414 
PipeFd2Dev(INT32 fd)415 STATIC struct PipeDev *PipeFd2Dev(INT32 fd)
416 {
417     struct PipeFdDev *devFd = PipeFdDevGet(fd);
418 
419     return (devFd != NULL) ? devFd->dev : NULL;
420 }
421 
PipeClose(INT32 fd)422 INT32 PipeClose(INT32 fd)
423 {
424     struct PipeDev *dev = NULL;
425     UINT32 openFlag;
426 
427     (VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
428     dev = PipeFd2Dev(fd);
429     if (dev == NULL) {
430         errno = ENODEV;
431         goto ERROR;
432     }
433     fd -= g_devStartFd;
434     openFlag = g_devFd[fd].openFlag;
435     g_devFd[fd].dev = NULL;
436     g_devFd[fd].openFlag = FALSE;
437     PipeDevFdFree(fd);
438     (VOID)LOS_MuxPost(g_devFdMutex);
439 
440     PIPE_DEV_LOCK(dev->mutex);
441     if (openFlag == O_RDONLY) {
442         dev->readerCnt--;
443     } else if (openFlag == O_WRONLY) {
444         dev->writerCnt--;
445     }
446 
447     if (dev->readerCnt == 0) {
448         PIPE_RW_POST(dev->writeSem);
449         PipePollNotify(dev, POLLOUT);
450     }
451 
452     if (dev->writerCnt == 0) {
453         PIPE_RW_POST(dev->readSem);
454         PipePollNotify(dev, POLLIN);
455     }
456 
457     if (--dev->ref == 0) {
458         PIPE_DEV_UNLOCK(dev->mutex);
459         (VOID)PipeDevUnregister(dev);
460     } else {
461         PIPE_DEV_UNLOCK(dev->mutex);
462     }
463 
464     return 0;
465 ERROR:
466     (VOID)LOS_MuxPost(g_devFdMutex);
467     return -1;
468 }
469 
PipeWriterIsWaiting(UINT32 sem)470 STATIC INLINE BOOL PipeWriterIsWaiting(UINT32 sem)
471 {
472     LosSemCB *semCB = GET_SEM(sem);
473     UINT32 num = 0;
474 
475     while (semCB->semCount == 0) {
476         UINT32 ret = LOS_SemPost(semCB->semID);
477         if (ret != LOS_OK) {
478             PRINT_ERR("pipe device write sem post error, ret = %x\n", ret);
479         }
480         num++;
481     }
482     return (num <= 1) ? FALSE : TRUE;
483 }
484 
PipeDevGet(INT32 fd)485 STATIC struct PipeDev *PipeDevGet(INT32 fd)
486 {
487     struct PipeDev *dev = NULL;
488 
489     (VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
490     dev = PipeFd2Dev(fd);
491     (VOID)LOS_MuxPost(g_devFdMutex);
492 
493     return dev;
494 }
495 
PipeRead(INT32 fd,VOID * buf,size_t len)496 INT32 PipeRead(INT32 fd, VOID *buf, size_t len)
497 {
498     struct PipeDev *dev = NULL;
499     INT32 ret;
500     size_t nread = 0;
501     size_t tmpLen;
502 
503     if ((buf == NULL) || (len == 0)) {
504         errno = EINVAL;
505         return -1;
506     }
507 
508     dev = PipeDevGet(fd);
509     if (dev == NULL) {
510         errno = ENODEV;
511         return -1;
512     }
513 
514     PIPE_DEV_LOCK(dev->mutex);
515     if ((dev->readIndex == dev->writeIndex) &&
516         (dev->roll == FALSE)) {
517         PIPE_DEV_UNLOCK(dev->mutex);
518 
519         ret = LOS_SemPend(dev->readSem, LOS_WAIT_FOREVER);
520         if (ret != LOS_OK) {
521             errno = EINVAL;
522             goto ERROR;
523         }
524         PIPE_DEV_LOCK(dev->mutex);
525     }
526 
527     while (nread < len) {
528         tmpLen = PipeRingbufferRead(dev, (CHAR *)buf + nread, len - nread);
529         if (tmpLen == 0) {
530             PIPE_RW_WAIT(dev->readSem);
531             /* No writer operates at present, which indicates that the write operation may have ended */
532             if (!PipeWriterIsWaiting(dev->writeSem)) {
533                 PipePollNotify(dev, POLLOUT);
534                 PIPE_DEV_UNLOCK(dev->mutex);
535                 return nread;
536             }
537             PipePollNotify(dev, POLLOUT);
538 
539             PIPE_DEV_UNLOCK(dev->mutex);
540             ret = LOS_SemPend(dev->readSem, LOS_WAIT_FOREVER);
541             if (ret != LOS_OK) {
542                 errno = EINVAL;
543                 goto ERROR;
544             }
545             PIPE_DEV_LOCK(dev->mutex);
546         }
547         nread += tmpLen;
548     }
549     PIPE_RW_POST(dev->writeSem);
550     PIPE_DEV_UNLOCK(dev->mutex);
551     PipePollNotify(dev, POLLOUT);
552 
553     return nread;
554 ERROR:
555     return -1;
556 }
557 
PipeWrite(INT32 fd,const VOID * buf,size_t len)558 INT32 PipeWrite(INT32 fd, const VOID *buf, size_t len)
559 {
560     struct PipeDev *dev = NULL;
561     INT32 ret;
562     size_t nwrite = 0;
563     size_t tmpLen;
564 
565     if ((buf == NULL) || (len == 0)) {
566         errno = EINVAL;
567         return -1;
568     }
569 
570     dev = PipeDevGet(fd);
571     if (dev == NULL) {
572         errno = ENODEV;
573         return -1;
574     }
575 
576     PIPE_DEV_LOCK(dev->mutex);
577     while (nwrite < len) {
578         tmpLen = PipeRingbufferWrite(dev, (char *)buf + nwrite, len - nwrite);
579         if (tmpLen == 0) {
580             PIPE_RW_POST(dev->readSem);
581             PipePollNotify(dev, POLLIN);
582             PIPE_RW_WAIT(dev->writeSem);
583 
584             PIPE_DEV_UNLOCK(dev->mutex);
585             ret = LOS_SemPend(dev->writeSem, LOS_WAIT_FOREVER);
586             if (ret != LOS_OK) {
587                 errno = EINVAL;
588                 goto ERROR;
589             }
590             PIPE_DEV_LOCK(dev->mutex);
591         }
592         nwrite += tmpLen;
593     }
594     PIPE_RW_POST(dev->readSem);
595     PipePollNotify(dev, POLLIN);
596     PIPE_DEV_UNLOCK(dev->mutex);
597 
598     return nwrite;
599 ERROR:
600     return -1;
601 }
602 
PipePoll(INT32 fd,struct PollTable * table)603 INT32 PipePoll(INT32 fd, struct PollTable *table)
604 {
605     struct PipeDev *dev = NULL;
606     struct PipeFdDev *devFd = NULL;
607     UINT32 openFlag;
608     INT32 mask;
609     size_t nbytes;
610     PollEvent event = 0;
611 
612     if (table == NULL) {
613         errno = EINVAL;
614         return -1;
615     }
616 
617     (VOID)LOS_MuxPend(g_devFdMutex, LOS_WAIT_FOREVER);
618     devFd = PipeFdDevGet(fd);
619     if (devFd == NULL) {
620         (VOID)LOS_MuxPost(g_devFdMutex);
621         errno = ENODEV;
622         return -1;
623     }
624     openFlag = devFd->openFlag;
625     dev = devFd->dev;
626     (VOID)LOS_MuxPost(g_devFdMutex);
627 
628     PIPE_DEV_LOCK(dev->mutex);
629     if (dev->readIndex == dev->writeIndex) {
630         if (dev->roll == TRUE) {
631             nbytes = dev->bufferSize;
632         } else {
633             nbytes = 0;
634         }
635     } else if (dev->writeIndex > dev->readIndex) {
636         nbytes = dev->writeIndex - dev->readIndex;
637     } else {
638         nbytes = dev->bufferSize - dev->readIndex + dev->writeIndex;
639     }
640 
641     if (((openFlag & O_WRONLY) != 0) && (nbytes < (dev->bufferSize - 1))) {
642         event |= POLLOUT;
643     }
644 
645     if (((openFlag & O_WRONLY) == 0) && (nbytes > 0)) {
646         event |= POLLIN;
647     }
648 
649     mask = event & table->event;
650     if (mask == 0) {
651         PollWait(&dev->wq, table);
652     }
653     PIPE_DEV_UNLOCK(dev->mutex);
654 
655     return mask;
656 }
657 
pipe(int filedes[2])658 int pipe(int filedes[2])
659 {
660     INT32 ret;
661     CHAR devName[PIPE_DEV_NAME_MAX] = {0};
662 
663     ret = PipeDevRegister(devName, PIPE_DEV_NAME_MAX);
664     if (ret < 0) {
665         errno = -ret;
666         return -1;
667     }
668 
669     struct PipeDev *dev = PipeDevFind(devName);
670     filedes[0] = open(devName, O_RDONLY);
671     if (filedes[0] < 0) {
672         (VOID)PipeDevUnregister(dev);
673         return -1;
674     }
675 
676     filedes[1] = open(devName, O_WRONLY);
677     if (filedes[1] < 0) {
678         (VOID)PipeDevUnregister(dev);
679         (VOID)close(filedes[0]);
680         return -1;
681     }
682 
683     return 0;
684 }
685 
OsPipeInit(VOID)686 UINT32 OsPipeInit(VOID)
687 {
688     UINT32 ret;
689 
690     ret = LOS_MuxCreate(&g_devListMutex);
691     if (ret != LOS_OK) {
692         return ret;
693     }
694 
695     ret = LOS_MuxCreate(&g_devFdMutex);
696     if (ret != LOS_OK) {
697         LOS_MuxDelete(g_devListMutex);
698         return ret;
699     }
700 
701     return LOS_OK;
702 }
703 #endif
704