• 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_fs.h"
35 #include "los_list.h"
36 #include "los_mux.h"
37 #include "los_sem.h"
38 #include "los_debug.h"
39 #include "los_memory.h"
40 #include "pipe_impl.h"
41 
42 #if (LOSCFG_POSIX_PIPE_API == 1)
43 
44 #define PIPE_DEV_NUM            32
45 #define PIPE_FD_NUM             (PIPE_DEV_NUM << 1)
46 #define PIPE_DEV_NAME_MAX       32
47 #define PIPE_DEV_FD_BITMAP_LEN  ((PIPE_FD_NUM >> 5) + 1)
48 #define PIPE_DEV_BUF_SIZE       1024
49 #define PIPE_READ               1
50 #define PIPE_WRITE              2
51 
52 #define PIPE_DEV_LOCK(mutex)    do {                            \
53     UINT32 __ret = LOS_MuxPend(mutex, LOS_WAIT_FOREVER);        \
54     if (__ret != LOS_OK) {                                      \
55         PRINT_ERR("pipe device lock error, ret = %x\n", __ret); \
56     }                                                           \
57 } while (0)
58 
59 #define PIPE_DEV_UNLOCK(mutex)    do {                            \
60     UINT32 __ret = LOS_MuxPost(mutex);                            \
61     if (__ret != LOS_OK) {                                        \
62         PRINT_ERR("pipe device unlock error, ret = %x\n", __ret); \
63     }                                                             \
64 } while (0)
65 
66 #define PIPE_RW_WAIT(sem)    do {                                           \
67     LosSemCB *__sem = GET_SEM(sem);                                         \
68     while (__sem->semCount != 0) {                                          \
69         UINT32 __ret = LOS_SemPend(__sem->semID, LOS_WAIT_FOREVER);         \
70         if (__ret != LOS_OK) {                                              \
71             PRINT_ERR("pipe device R/W sem wait error, ret = %x\n", __ret); \
72         }                                                                   \
73     }                                                                       \
74 } while (0)
75 
76 #define PIPE_RW_POST(sem)    do {                                           \
77     LosSemCB *__sem = GET_SEM(sem);                                         \
78     while (__sem->semCount == 0) {                                          \
79         UINT32 __ret = LOS_SemPost(__sem->semID);                           \
80         if (__ret != LOS_OK) {                                              \
81             PRINT_ERR("pipe device R/W sem post error, ret = %x\n", __ret); \
82         }                                                                   \
83     }                                                                       \
84 } while (0)
85 
86 struct PipeDev {
87     CHAR devName[PIPE_DEV_NAME_MAX];
88     UINT32 num;
89     UINT32 mutex;
90     LOS_DL_LIST list;
91     UINT32 readSem;
92     UINT32 writeSem;
93     UINT8 *ringBuffer;
94     size_t bufferSize;
95     size_t readIndex;
96     size_t writeIndex;
97     BOOL roll;
98     UINT32 readerCnt;
99     UINT32 writerCnt;
100     UINT32 ref;
101     struct PollWaitQueue wq;
102 };
103 
104 struct PipeFdDev {
105     struct PipeDev *dev;
106     BOOL openFlag;
107 };
108 
109 STATIC LOS_DL_LIST g_devList = {&g_devList, &g_devList};
110 STATIC UINT32 g_devListMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
111 
112 STATIC UINT32 g_devNumBitmap = 0;
113 STATIC UINT32 g_devFdBitmap[PIPE_DEV_FD_BITMAP_LEN] = {0};
114 STATIC struct PipeFdDev g_devFd[PIPE_FD_NUM] = {0};
115 STATIC UINT32 g_devFdMutex = LOSCFG_BASE_IPC_MUX_LIMIT;
116 STATIC INT32 g_devStartFd = 0;
117 
PipeDevNumAlloc(VOID)118 STATIC INT32 PipeDevNumAlloc(VOID)
119 {
120     UINT32 temp = g_devNumBitmap;
121     INT32 devNum = 0;
122 
123     while (temp & 0x1) {
124         devNum++;
125         temp = temp >> 1;
126     }
127 
128     if (devNum >= PIPE_DEV_NUM) {
129         return -1;
130     }
131     g_devNumBitmap |= 1U << devNum;
132 
133     return devNum;
134 }
135 
PipeDevNumFree(INT32 devNum)136 STATIC VOID PipeDevNumFree(INT32 devNum)
137 {
138     if ((devNum < 0) || (devNum >= PIPE_DEV_NUM)) {
139         return;
140     }
141     g_devNumBitmap &= ~(1U << devNum);
142 }
143 
PipeDevFind(const CHAR * path)144 STATIC struct PipeDev *PipeDevFind(const CHAR *path)
145 {
146     struct PipeDev *dev = NULL;
147 
148     (VOID)LOS_MuxPend(g_devListMutex, LOS_WAIT_FOREVER);
149     if (!LOS_ListEmpty(&g_devList)) {
150         LOS_DL_LIST_FOR_EACH_ENTRY(dev, &g_devList, struct PipeDev, list) {
151             if (!strncmp(dev->devName, path, PIPE_DEV_NAME_MAX)) {
152                 (VOID)LOS_MuxPost(g_devListMutex);
153                 return dev;
154             }
155         }
156     }
157     (VOID)LOS_MuxPost(g_devListMutex);
158     return NULL;
159 }
160 
PipeRingbufferRead(struct PipeDev * dev,VOID * buf,size_t len)161 STATIC size_t PipeRingbufferRead(struct PipeDev *dev, VOID *buf, size_t len)
162 {
163     size_t nbytes;
164 
165     if (dev->readIndex < dev->writeIndex) {
166         nbytes = dev->writeIndex - dev->readIndex;
167     } else if (dev->readIndex > dev->writeIndex) {
168         nbytes = dev->bufferSize - dev->readIndex;
169     } else {
170         if (dev->roll == FALSE) {
171             return 0;
172         } else {
173             nbytes = dev->bufferSize - dev->readIndex;
174         }
175     }
176     nbytes = (nbytes > len) ? len : nbytes;
177     (VOID)memcpy_s(buf, len, dev->ringBuffer + dev->readIndex, nbytes);
178     dev->readIndex += nbytes;
179     if (dev->readIndex >= dev->bufferSize) {
180         dev->readIndex = 0;
181         dev->roll = FALSE;
182     }
183 
184     return nbytes;
185 }
186 
PipeRingbufferWrite(struct PipeDev * dev,const VOID * buf,size_t len)187 STATIC size_t PipeRingbufferWrite(struct PipeDev *dev, const VOID *buf, size_t len)
188 {
189     size_t nbytes;
190 
191     if (dev->readIndex < dev->writeIndex) {
192         nbytes = dev->bufferSize - dev->writeIndex;
193     } else if (dev->readIndex > dev->writeIndex) {
194         nbytes = dev->readIndex - dev->writeIndex;
195     } else {
196         if (dev->roll == TRUE) {
197             return 0;
198         } else {
199             nbytes = dev->bufferSize - dev->writeIndex;
200         }
201     }
202 
203     nbytes = (nbytes > len) ? len : nbytes;
204     (VOID)memcpy_s(dev->ringBuffer + dev->writeIndex, dev->bufferSize
205                    - dev->writeIndex, buf, nbytes);
206     dev->writeIndex += nbytes;
207     if (dev->writeIndex >= dev->bufferSize) {
208         dev->roll = TRUE;
209         dev->writeIndex = 0;
210     }
211 
212     return nbytes;
213 }
214 
PipeDevRegister(CHAR * devName,UINT32 len)215 STATIC INT32 PipeDevRegister(CHAR *devName, UINT32 len)
216 {
217     INT32 ret;
218     INT32 num = PipeDevNumAlloc();
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     struct PipeDev *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