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