diff --git a/kernel/base/ipc/los_signal.c b/kernel/base/ipc/los_signal.c index fd5f5817786d931ff4c127678534121445e44ef3..df8bfd537f836dd58bfaa1b466d6853514581a4d 100644 --- a/kernel/base/ipc/los_signal.c +++ b/kernel/base/ipc/los_signal.c @@ -215,28 +215,22 @@ void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set) } } -int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldset) +int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl) { LosTaskCB *spcb = NULL; - sigset_t oldSigprocmask; int ret = LOS_OK; unsigned int intSave; sigset_t set; - int retVal; - if (setl != NULL) { - retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t)); - if (retVal != 0) { - return -EFAULT; - } - } SCHEDULER_LOCK(intSave); spcb = OsCurrTaskGet(); /* If requested, copy the old mask to user. */ - oldSigprocmask = spcb->sig.sigprocmask; - + if (oldsetl != NULL) { + *(sigset_t *)oldsetl = spcb->sig.sigprocmask; + } /* If requested, modify the current signal mask. */ if (setl != NULL) { + set = *(sigset_t *)setl; /* Okay, determine what we are supposed to do */ switch (how) { /* Set the union of the current set and the signal @@ -264,12 +258,6 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldset) } SCHEDULER_UNLOCK(intSave); - if (oldset != NULL) { - retVal = LOS_ArchCopyToUser(&(oldset->sig[0]), &oldSigprocmask, sizeof(sigset_t)); - if (retVal != 0) { - return -EFAULT; - } - } return ret; } diff --git a/syscall/fs_syscall.c b/syscall/fs_syscall.c index 3e7b921c8fc645d70cd5fc109a4e6397ef4b8279..f3e10416e50bcabe056fe451dc181c81513065d9 100644 --- a/syscall/fs_syscall.c +++ b/syscall/fs_syscall.c @@ -2516,37 +2516,36 @@ int SysFstatfs64(int fd, size_t sz, struct statfs *buf) int SysPpoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigMask, int nsig) { - int timeout; - int ret; - sigset_t_l origMask; - sigset_t_l setl; - - if (sigMask == NULL) { - ret = -EINVAL; - return ret; - } + int timeout, retVal; + sigset_t_l origMask = {0}; + sigset_t_l set = {0}; CHECK_ASPACE(tmo_p, sizeof(struct timespec)); - CHECK_ASPACE(sigMask, sizeof(sigset_t)); CPY_FROM_USER(tmo_p); - CPY_FROM_USER(sigMask); - timeout = (tmo_p == NULL) ? -1 : (tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS); - if (timeout & 0x80000000) { - ret = -EINVAL; - return ret; + if (tmo_p != NULL) { + timeout = tmo_p->tv_sec * OS_SYS_US_PER_MS + tmo_p->tv_nsec / OS_SYS_NS_PER_MS; + if (timeout < 0) { + return -EINVAL; + } + } else { + timeout = -1; } - setl.sig[0] = *sigMask; - OsSigprocMask(SIG_SETMASK, &setl, &origMask); - ret = SysPoll(fds, nfds, timeout); - if (ret < 0) { - ret = -get_errno(); + + if (sigMask != NULL) { + retVal = LOS_ArchCopyFromUser(&set, sigMask, sizeof(sigset_t)); + if (retVal != 0) { + return -EFAULT; + } + (VOID)OsSigprocMask(SIG_SETMASK, &set, &origMask); + } else { + (VOID)OsSigprocMask(SIG_SETMASK, NULL, &origMask); } - OsSigprocMask(SIG_SETMASK, &origMask, NULL); - PointerFree(tmo_pbak); - PointerFree(sigMaskbak); - return (ret == -1) ? -get_errno() : ret; + retVal = SysPoll(fds, nfds, timeout); + (VOID)OsSigprocMask(SIG_SETMASK, &origMask, NULL); + + return retVal; } int SysPselect6(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, diff --git a/syscall/ipc_syscall.c b/syscall/ipc_syscall.c index 628a966c9b5b6d75889c842030f5357d6f8e5862..83ebac4b35124952f5f17106b93af04df41012a2 100644 --- a/syscall/ipc_syscall.c +++ b/syscall/ipc_syscall.c @@ -29,6 +29,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "syscall_pub.h" #include "mqueue.h" #include #include @@ -36,6 +37,7 @@ #include "time_posix.h" #include "user_copy.h" #include "los_signal.h" +#include "los_process_pri.h" #include "los_strncpy_from_user.h" #include "fs/file.h" @@ -229,8 +231,14 @@ int SysSigAction(int sig, const sigaction_t *restrict sa, sigaction_t *restrict int SysSigprocMask(int how, const sigset_t_l *restrict setl, sigset_t_l *restrict oldl, size_t sigsetsize) { - /* Let nxsig_procmask do all of the work */ - return OsSigprocMask(how, setl, oldl); + CHECK_ASPACE(setl, sizeof(sigset_t_l)); + CHECK_ASPACE(oldl, sizeof(sigset_t_l)); + CPY_FROM_USER(setl); + CPY_FROM_USER(oldl); + /* Let OsSigprocMask do all of the work */ + int ret = OsSigprocMask(how, setl, oldl); + CPY_TO_USER(oldl); + return ret; } int SysKill(pid_t pid, int sig) diff --git a/syscall/syscall_pub.h b/syscall/syscall_pub.h index e784a51066ee85cbdf7e468c0ad3d7741e54980d..c118662136b436a604f6782823980c54f55d8067 100644 --- a/syscall/syscall_pub.h +++ b/syscall/syscall_pub.h @@ -110,7 +110,7 @@ Please deal with the "char *" by function:UserPathCopy. #define CPY_FROM_USER(ptr) \ __typeof(*ptr) ptr##cpy = {0}, *ptr##bak = ptr; \ if (ptr != NULL) { \ - if (LOS_ArchCopyFromUser((void*)&ptr##cpy, ptr, sizeof(*ptr)) != 0) { \ + if (LOS_ArchCopyFromUser((void*)&ptr##cpy, ptr##bak, sizeof(*ptr##bak)) != 0) { \ set_errno(EFAULT); \ return -get_errno(); \ } \ diff --git a/testsuites/unittest/IO/BUILD.gn b/testsuites/unittest/IO/BUILD.gn index 7eb948e44612a497be83be025109d99276863999..fe03995ab7a2fdaf7c1c0d4de2ba439281ba6e8d 100644 --- a/testsuites/unittest/IO/BUILD.gn +++ b/testsuites/unittest/IO/BUILD.gn @@ -85,6 +85,7 @@ sources_full = [ "full/IO_test_strncasecmp_l_002.cpp", "full/IO_test_ppoll_001.cpp", "full/IO_test_ppoll_002.cpp", + "full/IO_test_ppoll_003.cpp", "full/IO_test_pselect_001.cpp", "full/IO_test_pselect_002.cpp", ] diff --git a/testsuites/unittest/IO/It_test_IO.h b/testsuites/unittest/IO/It_test_IO.h index 5c763ca3f60069b69922c652c664c6ddf54c9767..353010d37a3981192d947e7da53325cf48b0b36a 100644 --- a/testsuites/unittest/IO/It_test_IO.h +++ b/testsuites/unittest/IO/It_test_IO.h @@ -127,13 +127,12 @@ extern VOID IO_TEST_DCNGETTEXT_002(VOID); extern VOID IO_TEST_DCGETTEXT_001(VOID); extern VOID IO_TEST_DCGETTEXT_002(VOID); extern VOID IO_TEST_GETTEXT_001(VOID); -extern VOID IO_TEST_PPOLL_001(void); -extern VOID IO_TEST_PPOLL_002(void); extern VOID IO_TEST_PSELECT_001(void); extern VOID IO_TEST_PSELECT_002(void); extern VOID IO_TEST_STRFMON_L_001(VOID); extern VOID IO_TEST_STRFMON_L_002(VOID); extern VOID IO_TEST_PPOLL_001(VOID); extern VOID IO_TEST_PPOLL_002(VOID); +extern VOID IO_TEST_PPOLL_003(VOID); #endif diff --git a/testsuites/unittest/IO/full/IO_test_ppoll_001.cpp b/testsuites/unittest/IO/full/IO_test_ppoll_001.cpp index 66d6c06d79169a0317ac642e8068a671756bdf5f..e80b1858d7dc3248f2231550334ef87eec0e9893 100644 --- a/testsuites/unittest/IO/full/IO_test_ppoll_001.cpp +++ b/testsuites/unittest/IO/full/IO_test_ppoll_001.cpp @@ -30,143 +30,91 @@ */ #include "It_test_IO.h" -#include -#include "signal.h" #include "pthread.h" -#define LISTEN_FD_NUM 10 -#define POLL_EVENTS 1 +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; -int pipeFdPpoll[LISTEN_FD_NUM][2]; -static pthread_t g_tid = -1; -extern int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask); +static INT32 pipeFdPpoll[2]; +static INT32 g_step = 1; +static CHAR strBuf[] = "hello world."; +static struct pollfd pfd; -static void *pthread_01(void) +static void *pthread_01(void *arg) { - static int count = 0; - int total_num = 0; - int times = 3; - int i, ret; - struct pollfd fds[LISTEN_FD_NUM] = { 0 }; - char buffer[20]; - struct timespec t = { 3,0 }; - sigset_t sigset; - - /* TEST_PRINT("[INFO]%s:%d,%s,Create thread %d\n", __FILE__, __LINE__, __func__, count); */ - count++; - - sigemptyset(&sigset); - sigaddset(&sigset, SIGALRM); /* 把SIGALRM 信号添加到sigset 信号集中 */ - sigaddset(&sigset, SIGUSR1); - - for (i = 0; i < LISTEN_FD_NUM; i++) { - fds[i].fd = pipeFdPpoll[i][0]; - fds[i].events = POLL_EVENTS; + INT32 retVal; + CHAR buf[BUF_SIZE]; + + /* 执行ppoll监视文件描述符 */ + while (g_step < 3) { /* 3, 3rd step */ + usleep(DELAY_TIME); } - - while (times--) { - ret = ppoll(fds, LISTEN_FD_NUM, &t, &sigset); - total_num += ((ret > 0) ? ret : 0); - - if (ret <= 0) { - continue; - } - - for (i = 0; i < LISTEN_FD_NUM; i++) { - if (fds[i].revents & POLL_EVENTS) { - ret = read(fds[i].fd, buffer, 12); - ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); - ret = strcmp(buffer, "hello world"); - TEST_PRINT("[EVENT]%s:%d,%s,buffer=%s\n", __FILE__, __LINE__, __func__, buffer); - } - } - - if (total_num == LISTEN_FD_NUM) { - break; - } + g_step++; + retVal = ppoll(&pfd, 1, NULL, NULL); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); } - - /* ICUNIT_GOTO_EQUAL(total_num, 10, -1, EXIT); */ - /* TEST_PRINT("[INFO]%s:%d,%s,total_num=%d\n", __FILE__, __LINE__, __func__, total_num); */ -EXIT: - return nullptr; -} - -static UINT32 testcase1(VOID) -{ - int i; - int ret; - int count = 0; - - for (i = 0; i < LISTEN_FD_NUM; i++) { - ret = pipe(pipeFdPpoll[i]); - ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,pipeFdPpoll[%d][0]=%d\n", __FILE__, __LINE__, __func__, ret, i, pipeFdPpoll[i][0]); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,pipeFdPpoll[%d][0]=%d\n", __FILE__, __LINE__, __func__, ret, i, pipeFdPpoll[i][1]); + g_step++; + + /* 判断revents */ + if (pfd.revents & POLLIN) { + memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); } - - errno = 0; - ret = pthread_create(&g_tid, nullptr, (void *(*)(void *))pthread_01, nullptr); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); - ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); - - errno = 0; - for (i = 0; i < LISTEN_FD_NUM; i++) { - if ((pipeFdPpoll[i][1] != 9) && (pipeFdPpoll[i][1] != 10) && (pipeFdPpoll[i][1] != 11)) { - ret = write(pipeFdPpoll[i][1], "hello world!", 12); /* 12, "hello world" length and '\0' */ - } - ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); + + while (g_step < 6) { /* 6, 6th step */ + usleep(DELAY_TIME); } + pthread_exit(NULL); +} -#if 1 /* write looply */ - while(1) { - if (count++ > 3) { - break; - } - sleep(1); - for (i = 0; i < LISTEN_FD_NUM; i++) { - errno = 0; - ret = pthread_create(&g_tid, nullptr, (void *(*)(void *))pthread_01, nullptr); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); - ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); - - if ((pipeFdPpoll[i][1] == 13) || (pipeFdPpoll[i][1] == 14) || (pipeFdPpoll[i][1] == 15)) { - errno = 0; - ret = write(pipeFdPpoll[i][1], "World HELLO!", 12); /* 12, "hello world" length and '\0' */ - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,errno=%d,errstr=%s\n", __FILE__, __LINE__, __func__, ret, errno, strerror(errno)); - TEST_PRINT("[INFO]%s:%d,%s,ret=%d,pipeFdPpoll[%d][1]=%d,count=%d\n", __FILE__, __LINE__, __func__, ret,i, pipeFdPpoll[i][1], count); - } - /* ICUNIT_GOTO_EQUAL(ret, 12, ret, EXIT); */ - } +STATIC UINT32 testcase(VOID) +{ + INT32 retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { /* 1, 1st step */ + usleep(DELAY_TIME); } -#endif - - pthread_join(g_tid, nullptr); - - for (i = 0; i < LISTEN_FD_NUM; i++) { - close(pipeFdPpoll[i][0]); - close(pipeFdPpoll[i][1]); + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + /* 设置pfd */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + + /* 开辟线程执行 ppoll */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); } - - return LOS_OK; - -EXIT: - for (i = 0; i < LISTEN_FD_NUM; i++) { - close(pipeFdPpoll[i][0]); - close(pipeFdPpoll[i][1]); + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + + /* 向管道写入数据 */ + while (g_step < 4) { /* 4, 4th step */ + usleep(DELAY_TIME); } - return LOS_NOK; -} - -static UINT32 testcase(VOID) -{ - testcase1(); - + sleep(1); + + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + pthread_join(tid, NULL); + return LOS_OK; } VOID IO_TEST_PPOLL_001(VOID) { TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); -} +} \ No newline at end of file diff --git a/testsuites/unittest/IO/full/IO_test_ppoll_002.cpp b/testsuites/unittest/IO/full/IO_test_ppoll_002.cpp index ae52d92710cf69e4a455a1b687223514bb8ddb6c..9f121a79094ad4471551d846b99da72074f10350 100644 --- a/testsuites/unittest/IO/full/IO_test_ppoll_002.cpp +++ b/testsuites/unittest/IO/full/IO_test_ppoll_002.cpp @@ -30,83 +30,87 @@ */ #include "It_test_IO.h" -#include "time.h" #include "signal.h" -#include -#include -#include -#include +#include "pthread.h" -#define BUF_LEN 20 -#define MAX_SCAN_FDSET 10 /* define poll's listened FD set's size */ -#define POLL_WAIT_TIMEOUT 10*1000 /* ms */ +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; -extern int ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout, const sigset_t *sigmask); -void work_ppoll(int fd) -{ - int ret = 0; - int i = 0; - char recv_buf[BUF_LEN]; - sigset_t sigset; - struct timespec t; - struct pollfd scan_fdset[MAX_SCAN_FDSET]; - int scan_fdset_num = 10; - int count = 5; - - bzero(recv_buf, BUF_LEN); - sigemptyset(&sigset); - sigaddset(&sigset, SIGALRM); /* add SIGALRM to sigset */ - sigaddset(&sigset, SIGUSR1); /* add SIGUSR1 to sigset */ - bzero(&t, sizeof(struct timespec)); - t.tv_sec = 10; - t.tv_nsec = 0; - bzero(scan_fdset, sizeof(struct pollfd) * MAX_SCAN_FDSET); - scan_fdset[0].fd = fd; - - /* attention:in the book《UNIX网络编程第一卷》P162 metions:POLLERR,POLLHUP,POLLNVAL\ - those error signals can not be set in events. */ - /* they will return in revents,while the proper condition happens. */ - scan_fdset[0].events = POLLOUT; /* set the signal needed to be listened:POLLOUT/POLLIN */ +static int pipeFdPpoll[2]; +static int g_step = 1; +static char strBuf[] = "hello world."; +static struct pollfd pfd; - /* set other elements in the array as invalid. */ - for (i = 1; i < MAX_SCAN_FDSET; i++) { - /* scan_fdset[i].fd = -1; */ - scan_fdset[i].fd = fd; - scan_fdset[i].events = POLLOUT; /* set the signal needed to be listened. */ +static void *pthread_01(void *arg) +{ + int retVal; + char buf[BUF_SIZE]; + const struct timespec timeout = {10000, 0}; + + /* 执行ppoll监视文件描述符 */ + while (g_step < 4) { /* 4, 4th step */ + usleep(DELAY_TIME); } - /* scan_fdset_num = 1; */ /* 表示当前的scan_fdset[] 数组中只使用前面1 个元素存放需要监听的扫描符 */ - - while (count--) { - ret = ppoll(scan_fdset, scan_fdset_num, &t, &sigset); - - for (i = 0; i < MAX_SCAN_FDSET; i++) { - if (scan_fdset[i].revents & POLLOUT) { - TEST_PRINT("[INFO]%s:%d,%s,fd have signal!\n", __FILE__, __LINE__, __func__); - ret = read(fd, recv_buf, BUF_LEN); - if (-1 == ret) { - TEST_PRINT("[INFO]%s:%d,%s,read error!\n", __FILE__, __LINE__, __func__); - continue; - } - TEST_PRINT("[INFO]%s:%d,%s,recv_buf=%s\n", __FILE__, __LINE__, __func__, recv_buf); - } - TEST_PRINT("[INFO]%s:%d,%s,scan_fdset[i].revents=%d\n", __FILE__, __LINE__, __func__, scan_fdset[i].revents); - } + g_step++; + retVal = ppoll(&pfd, 1, &timeout, NULL); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + /* 判断revents */ + if (pfd.revents & POLLIN) { + memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); } + + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); + } + pthread_exit(NULL); } static UINT32 testcase(VOID) { - int fd; - char *filename = FILEPATH_775; + int retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { + usleep(DELAY_TIME); + } + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; + + /* 设置pfd */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + + /* 向管道写入数据 */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); + } + sleep(1); + + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + g_step++; - fd = open(filename, O_RDWR); - TEST_PRINT("[INFO]%s:%d,%s,fd=%d\n", __FILE__, __LINE__, __func__, fd); - work_ppoll(fd); + /* 开辟线程执行 ppoll */ + while (g_step < 3) { /* 3, 3rd step */ + usleep(DELAY_TIME); + } + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + pthread_join(tid, NULL); + return LOS_OK; } VOID IO_TEST_PPOLL_002(VOID) { TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); -} +} \ No newline at end of file diff --git a/testsuites/unittest/IO/full/IO_test_ppoll_003.cpp b/testsuites/unittest/IO/full/IO_test_ppoll_003.cpp new file mode 100755 index 0000000000000000000000000000000000000000..ea0852f4997d94b1bb9e4c7ec895a81dac962b24 --- /dev/null +++ b/testsuites/unittest/IO/full/IO_test_ppoll_003.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "It_test_IO.h" +#include "pthread.h" +#include "signal.h" + +const int BUF_SIZE = 128; +const int DELAY_TIME = 200; + +static INT32 pipeFdPpoll[2]; +static INT32 g_step = 1; +static CHAR strBuf[] = "hello world."; +static struct pollfd pfd; +static sigset_t sigMask; +static UINT32 count = 0; + +static void signalHandle(INT32 sigNum) +{ + g_step++; + return; +} + +static void *pthread_01(void *arg) +{ + INT32 retVal; + CHAR buf[BUF_SIZE]; + + (void)signal(SIGUSR1, signalHandle); + + while (1) { + /* 执行ppoll监视文件描述符 */ + while (g_step < 2) { /* 2, 2nd step */ + usleep(DELAY_TIME); + } + g_step++; + retVal = ppoll(&pfd, 1, NULL, &sigMask); + + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + /* 判断revents */ + if (pfd.revents & POLLIN) { + memset_s(buf, sizeof(buf), 0, sizeof(buf)); + retVal = read(pfd.fd, buf, BUF_SIZE); + ICUNIT_ASSERT_NOT_EQUAL_NULL(retVal, -1, retVal); + + retVal = strcmp(strBuf, buf); + ICUNIT_ASSERT_EQUAL_NULL(retVal, 0, retVal); + + count++; + } else { + ICUNIT_ASSERT_NOT_EQUAL_NULL(pfd.revents & POLLIN, 0, pfd.revents & POLLIN); + } + g_step++; + + if (g_step >= 7) { /* 7, 7th step */ + ICUNIT_ASSERT_EQUAL_NULL(count, 2, count); /* 2, 2nd step */ + pthread_exit(NULL); + } + } + + return LOS_OK; +} + +static UINT32 testcase(VOID) +{ + INT32 retVal; + pthread_t tid; + + /* 建立管道 */ + while (g_step < 1) { + usleep(DELAY_TIME); + } + retVal = pipe(pipeFdPpoll); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + /* 设置pfd sigmask */ + pfd.fd = pipeFdPpoll[0]; + pfd.events = POLLIN; + pfd.revents = 0x0; + + sigemptyset(&sigMask); + sigaddset(&sigMask, SIGUSR1); + + /* 开辟线程执行 ppoll */ + retVal = pthread_create(&tid, NULL, pthread_01, NULL); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + g_step++; + + /* 向管道写入数据 */ + while (g_step < 3) { /* 3, 3ed step */ + usleep(DELAY_TIME); + } + sleep(1); /* 保证先挂起再写入数据 */ + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + /* 向线程发送信号 */ + while (g_step < 5) { /* 5, 5th step */ + usleep(DELAY_TIME); + } + sleep(1); /* 保证先挂起再发送信号 */ + retVal = pthread_kill(tid, SIGUSR1); + ICUNIT_ASSERT_EQUAL(retVal, 0, retVal); + + /* 继续向管道写入数据 */ + ICUNIT_ASSERT_EQUAL(g_step, 5, g_step); /* 5, sth。判断挂起解除之前信号没有被处理 */ + retVal = write(pipeFdPpoll[1], "hello world.", sizeof(strBuf)); + ICUNIT_ASSERT_NOT_EQUAL(retVal, -1, retVal); + + while (g_step < 7) { /* 7, 7th step */ + usleep(DELAY_TIME); + } + ICUNIT_ASSERT_EQUAL(count, 2, count); /* 2, 2nd step */ + /* 等待退出 */ + pthread_join(tid, NULL); + + return LOS_OK; +} + +VOID IO_TEST_PPOLL_003(VOID) +{ + TEST_ADD_CASE(__FUNCTION__, testcase, TEST_LIB, TEST_LIBC, TEST_LEVEL1, TEST_FUNCTION); +} \ No newline at end of file diff --git a/testsuites/unittest/IO/io_test.cpp b/testsuites/unittest/IO/io_test.cpp index 5b8f668d8ca2608f2cf16f2e2e988eae7afc00f4..cda694752160b4b91f658bc68c63021f34026ca9 100644 --- a/testsuites/unittest/IO/io_test.cpp +++ b/testsuites/unittest/IO/io_test.cpp @@ -137,6 +137,17 @@ HWTEST_F(IoTest, IO_TEST_PPOLL_002, TestSize.Level0) IO_TEST_PPOLL_002(); } +/* * + * @tc.name: IO_TEST_PPOLL_003 + * @tc.desc: function for IoTest + * @tc.type: FUNC + * @tc.require: AR000EEMQ9 + */ +HWTEST_F(IoTest, IO_TEST_PPOLL_003, TestSize.Level0) +{ + IO_TEST_PPOLL_003(); +} + /* * * @tc.name: IT_STDLIB_POLL_002 * @tc.desc: function for IoTest