熊卓孜
f55906dee6
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
...
# Conflicts:
# kernel_liteos_a-master/testsuites/unittest/process/basic/pthread/smoke/pthread_atfork_test_002.cpp
# kernel_liteos_a-master/testsuites/unittest/process/basic/pthread/smoke/pthread_cond_test_001.cpp
7 months ago
熊卓孜
222949d5be
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜
fe05466eeb
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
熊卓孜
796b79839f
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
Lvwenxuan
768b870f5b
#include "it_pthread_test.h" // 包含测试框架的头文件
...
// 全局变量定义
static int g_number = 0; // 用于记录 InitRoutine 被调用的次数
static int g_okStatus = 777; // 定义一个特殊的状态值,表示状态正常
static pthread_once_t g_onceCtrl = PTHREAD_ONCE_INIT; // pthread_once 的控制变量,初始化为未执行状态
// 初始化函数,每次调用都会增加 g_number 的值
static void InitRoutine(void)
{
g_number++;
}
// 线程函数,测试 pthread_once 的行为
static void *Threadfunc(void *parm)
{
int err;
// 确保 InitRoutine 只被调用一次
err = pthread_once(&g_onceCtrl, InitRoutine);
ICUNIT_GOTO_EQUAL(err, 0, err, EXIT); // 使用测试框架的宏检查 pthread_once 的返回值是否为 0
return reinterpret_cast<void *>(g_okStatus); // 返回状态值
EXIT:
return NULL; // 出错时返回 NULL
}
// 测试函数,创建多个线程并检查 pthread_once 的行为
static void *ThreadFuncTest(void *arg)
{
pthread_t thread[3]; // 定义线程数组,用于存储线程 ID
int rc = 0; // 用于存储线程创建和加入的返回值
int i = 3; // 循环变量,但立即被重新赋值,这里可能是代码风格问题
void *status; // 用于存储线程函数的返回值
const int threadsNum = 3; // 定义线程数量
g_number = 0; // 重置全局计数器
// 创建多个线程
for (i = 0; i < threadsNum; ++i) {
rc = pthread_create(&thread[i], NULL, Threadfunc, NULL);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查 pthread_create 的返回值
}
// 等待所有线程结束
for (i = 0; i < threadsNum; ++i) {
rc = pthread_join(thread[i], &status);
ICUNIT_GOTO_EQUAL(rc, 0, rc, EXIT); // 检查 pthread_join 的返回值
ICUNIT_GOTO_EQUAL((unsigned int)status, (unsigned int)g_okStatus, status, EXIT); // 检查线程函数的返回值
}
// 检查 InitRoutine 是否只被调用了一次
ICUNIT_GOTO_EQUAL(g_number, 1, g_number, EXIT);
EXIT:
return NULL; // 出错时返回 NULL
}
// 测试用例函数,设置线程属性并启动测试线程
static int Testcase(void)
{
int ret; // 用于存储函数调用的返回值
pthread_t newPthread; // 定义新线程的 ID
int curThreadPri, curThreadPolicy; // 用于存储当前线程的调度策略和优先级
pthread_attr_t a = { 0 }; // 定义线程属性对象并初始化
struct sched_param param = { 0 }; // 定义调度参数对象并初始化
g_onceCtrl = PTHREAD_ONCE_INIT; // 重置 pthread_once 的控制变量
// 获取当前线程的调度策略和优先级
ret = pthread_getschedparam(pthread_self(), &curThreadPolicy, ¶m);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 检查 pthread_getschedparam 的返回值
curThreadPri = param.sched_priority; // 获取当前线程的优先级
// 设置新线程的属性
ret = pthread_attr_init(&a); // 初始化线程属性
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); // 设置线程继承调度策略为显式
param.sched_priority = curThreadPri + 2; // 设置新线程的优先级为当前线程优先级加 2
pthread_attr_setschedparam(&a, ¶m); // 设置线程调度参数
ret = pthread_create(&newPthread, &a, ThreadFuncTest, 0); // 创建新线程并运行测试函数
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查 pthread_create 的返回值
// 等待新线程结束
ret = pthread_join(newPthread, NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查 pthread_join 的返回值
return 0; // 测试成功结束
}
// 注册测试用例
void ItTestPthreadOnce001(void)
{
TEST_ADD_CASE("IT_PTHREAD_ONCE_001", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION); // 使用测试框架的宏注册测试用例
}
7 months ago
Lvwenxuan
b04c0c9f54
#include "it_pthread_test.h" // 引入测试相关的头文件
...
/* ***************************************************************************
* Public Functions
* ************************************************************************** */
// 定义全局变量用于存储当前线程的优先级、策略和测试线程计数
static int g_currThreadPri, g_currThreadPolicy;
static int g_testPthredCount;
// 线程函数,用于测试线程调度策略和优先级
static void *ThreadFuncTest2(void *arg)
{
(void)arg; // 未使用参数,避免编译器警告
int ret; // 存放函数返回值
int policy; // 存放调度策略
struct sched_param param = { 0 }; // 初始化调度参数结构体
pthread_t pthread = pthread_self(); // 获取当前线程ID
g_testPthredCount++; // 测试线程计数加1
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread, &policy, ¶m);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 检查返回值,如果不为0则跳转到EXIT标签
// 验证当前线程的优先级和策略是否与全局变量一致
ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT);
ICUNIT_GOTO_EQUAL(g_currThreadPolicy, policy, policy, EXIT);
// 验证是否创建了2个测试线程
ICUNIT_GOTO_EQUAL(g_testPthredCount, 2, g_testPthredCount, EXIT);
EXIT: // 错误处理或正常退出的标签
return NULL;
}
// 另一个线程函数,用于测试SCHED_FIFO策略
static void *ThreadFuncTest3(void *arg)
{
(void)arg; // 未使用参数,避免编译器警告
int ret; // 存放函数返回值
int policy; // 存放调度策略
struct sched_param param = { 0 }; // 初始化调度参数结构体
pthread_t pthread = pthread_self(); // 获取当前线程ID
g_testPthredCount++; // 测试线程计数加1
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread, &policy, ¶m);
ICUNIT_GOTO_EQUAL(ret, 0, ret, EXIT); // 检查返回值,如果不为0则跳转到EXIT标签
// 验证当前线程的优先级和策略是否与预期一致
ICUNIT_GOTO_EQUAL(g_currThreadPri, param.sched_priority, param.sched_priority, EXIT);
ICUNIT_GOTO_EQUAL(policy, SCHED_FIFO, policy, EXIT);
// 验证是否创建了4个测试线程
ICUNIT_GOTO_EQUAL(g_testPthredCount, 4, g_testPthredCount, EXIT);
EXIT: // 错误处理或正常退出的标签
return NULL;
}
// 测试用例函数
static int Testcase()
{
struct sched_param param = { 0 }; // 初始化调度参数结构体
int ret; // 存放函数返回值
void *res = NULL; // 用于存放线程函数的返回值
pthread_attr_t a = { 0 }; // 初始化线程属性结构体(此处未使用)
pthread_t newPthread, newPthread1; // 定义线程ID变量(注意:newPthread1未使用)
g_testPthredCount = 0; // 初始化测试线程计数
// 获取当前线程的调度策略和参数
ret = pthread_getschedparam(pthread_self(), &g_currThreadPolicy, ¶m);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 检查返回值
g_currThreadPri = param.sched_priority; // 保存当前线程的优先级
g_testPthredCount++; // 测试线程计数加1(此处应为初始化后的第一个操作,但计数逻辑稍显混乱)
// 创建第一个测试线程
ret = pthread_create(&newPthread, NULL, ThreadFuncTest2, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 等待第一个测试线程结束
ret = pthread_join(newPthread, &res);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 验证是否创建了2个测试线程(逻辑上应在此处验证,但前面已有验证)
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 2, g_testPthredCount);
g_testPthredCount++; // 测试线程计数再加1,准备创建下一个线程
// 设置当前线程的调度策略为SCHED_FIFO,并设置优先级
param.sched_priority = g_currThreadPri;
ret = pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 尝试重新创建并使用已定义的newPthread变量(这里应使用不同的变量名以避免混淆)
ret = pthread_create(&newPthread, NULL, ThreadFuncTest3, 0);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 等待第二个测试线程结束
ret = pthread_join(newPthread, &res);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
// 验证是否创建了4个测试线程(实际只创建了2个,此处逻辑有误)
ICUNIT_ASSERT_EQUAL(g_testPthredCount, 4, g_testPthredCount);
// 恢复当前线程的调度策略为SCHED_RR,并设置优先级
param.sched_priority = g_currThreadPri;
ret = pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 检查返回值
return 0; // 测试用例结束
}
// 注册测试用例到测试框架中
void ItTestPthread003(void)
{
TEST_ADD_CASE("IT_POSIX_PTHREAD_003", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
// 注册一个名为"IT_POSIX_PTHREAD_003"的测试用例,指定测试函数为Testcase,并设置相关测试属性
}
7 months ago
Lvwenxuan
77f2c2e021
#include "it_pthread_test.h" // 引入测试相关的头文件,可能包含测试宏定义和函数声明
...
// 定义全局变量
static pthread_barrier_t g_barrier; // 线程同步屏障
static int g_testToCount001 = 0; // 用于记录线程函数被调用的次数
static int g_threadTest[10]; // 用于存储线程函数的输出结果
// 线程函数0,用于测试
static void *ThreadFuncTest0(void *a)
{
int ret; // 用于存储函数返回值
int count = *((int *)a); // 从参数中获取线程编号
g_testToCount001++; // 增加全局计数器
// 等待所有线程到达屏障点
ret = pthread_barrier_wait(&g_barrier);
// 使用自定义的断言宏检查返回值,期望是PTHREAD_BARRIER_SERIAL_THREAD(表示是最后一个到达屏障的线程)
// 但这里可能是一个误解,因为pthread_barrier_wait通常不返回PTHREAD_BARRIER_SERIAL_THREAD,而是返回0或错误码
// 此处可能是想检查是否是某个特定行为,但实现方式有误
ICUNIT_GOTO_EQUAL(ret, PTHREAD_BARRIER_SERIAL_THREAD, ret, EXIT);
g_threadTest[count] = count; // 存储线程编号到全局数组
EXIT: // 标记退出点,用于自定义断言宏中的跳转
return NULL;
}
// 线程函数2,与ThreadFuncTest0类似,但断言检查返回值是否为0
static void *ThreadFuncTest2(void *a)
{
// ...(与ThreadFuncTest0类似,省略具体实现)
// 注意:这里的断言检查期望返回值是0,这是正确的,因为pthread_barrier_wait通常返回0表示成功
}
// 线程函数1,与ThreadFuncTest2类似,但命名为Test1
static void *ThreadFuncTest1(void *a)
{
// ...(与ThreadFuncTest2几乎相同,省略具体实现)
}
// 测试用例函数
static int Testcase(void)
{
struct sched_param param = { 0 }; // 定义线程调度参数结构体并初始化
int ret; // 用于存储函数返回值
void *res = NULL; // 通常用于pthread_join的返回值,但此处未使用
pthread_attr_t a = { 0 }; // 定义线程属性结构体并初始化
pthread_t thread; // 声明一个pthread_t类型的变量,但后续未使用
pthread_t newPthread[10], newPthread1; // 声明线程ID数组和一个额外的线程ID,但newPthread1未使用
pthread_mutexattr_t mutex; // 声明互斥锁属性结构体,但后续未使用
int index = 0; // 用于循环的索引
int currThreadPri, currThreadPolicy; // 用于存储当前线程的优先级和策略
int threadParam[10]; // 用于存储传递给线程函数的参数
// 获取当前线程的调度参数
ret = pthread_getschedparam(pthread_self(), &currThreadPolicy, ¶m);
ICUNIT_ASSERT_EQUAL(ret, 0, -ret); // 使用自定义断言宏检查返回值
currThreadPri = param.sched_priority; // 获取当前线程的优先级
const int testCount = 10; // 定义测试中的线程数量
// 初始化全局变量和线程属性
g_testToCount001 = 0;
ret = pthread_attr_init(&a);
pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED); // 设置线程属性为显式调度
param.sched_priority = currThreadPri - 1; // 设置线程优先级比当前线程低
pthread_attr_setschedparam(&a, ¶m); // 设置线程属性中的调度参数
// 初始化屏障,设置参与屏障的线程数量为testCount
ret = pthread_barrier_init(&g_barrier, NULL, testCount);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 创建线程并传递参数
threadParam[0] = 0;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest0, &threadParam[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
g_threadTest[0] = 0; // 初始化全局数组的第一个元素
// 循环创建剩余的线程(除了最后一个,用于测试不同的线程函数)
index = 1;
while (index < (testCount - 1)) {
threadParam[index] = index;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest1, &threadParam[index]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
g_threadTest[index] = 0; // 初始化全局数组的元素
index++;
}
// 检查在所有线程创建之前,全局计数器是否已正确增加
ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount - 1, g_testToCount001);
// 创建最后一个线程,使用不同的线程函数
threadParam[index] = index;
ret = pthread_create(&newPthread[index], &a, ThreadFuncTest2, &threadParam[index]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 等待所有线程启动(这里使用sleep是一个简单但不精确的方法)
sleep(1);
// 检查全局计数器是否已达到预期的线程数量
ICUNIT_ASSERT_EQUAL(g_testToCount001, testCount, g_testToCount001);
// 等待所有线程结束
index = 0;
while (index < testCount) {
ret = pthread_join(newPthread[index], NULL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
// 检查每个线程的输出结果是否正确
ICUNIT_ASSERT_EQUAL(g_threadTest[index], index, g_threadTest[index]);
index++;
}
// 销毁屏障
ret = pthread_barrier_destroy(&g_barrier);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 使用自定义断言宏检查返回值
return 0; // 测试用例成功结束
}
// 将测试用例添加到测试套件中
void ItTestPthread006(void)
{
// 使用自定义宏将测试用例添加到测试框架中
// 宏参数可能包括测试用例的名称、函数指针、测试分类、内存要求、测试级别和函数类型
TEST_ADD_CASE("IT_POSIX_PTHREAD_006", Testcase, TEST_POSIX, TEST_MEM, TEST_LEVEL0, TEST_FUNCTION);
}
7 months ago
Lvwenxuan
feebadef06
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
Lvwenxuan
30c5b2fb9c
#include <cstdio> // 引入标准输入输出库(本例中未直接使用)
...
#include <unistd.h> // 引入POSIX操作系统API,提供mkdir(), rmdir()等函数
#include <cstdlib> // 引入C标准库函数(本例中未直接使用)
#include <fcntl.h> // 引入文件控制选项,用于open()函数
#include <cstring> // 引入字符串操作函数(本例中未直接使用)
#include <gtest/gtest.h> // 引入Google Test框架,提供断言宏
#include "It_process_plimits.h" // 引入自定义头文件,可能包含WriteFile()等函数的声明
// 定义测试函数ItProcessPlimitsDevices009
void ItProcessPlimitsDevices009(void)
{
int fd; // 声明文件描述符变量
int ret; // 声明返回值变量,用于存储函数调用的结果
mode_t mode; // 声明文件模式变量,但此处未初始化,存在潜在问题
std::string test_dev = "/dev/hi_mipi"; // 定义测试设备文件路径
std::string device_a = "a"; // 定义设备访问控制规则,但此处规则不完整(通常应包含用户组和权限,如"a * rwm")
std::string path = "/proc/plimits/test"; // 定义测试目录路径
std::string devicesDenyPath = "/proc/plimits/test/devices.deny"; // 定义设备拒绝列表文件路径
// 尝试创建目录,但mode未初始化,可能导致行为不确定
// 正确的做法是指定一个明确的权限位,如0755,但此处我们假设关注的是目录的创建
ret = mkdir(path.c_str(), S_IFDIR | mode); // 尝试创建/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言创建目录操作成功(返回值为0)
// 尝试将设备拒绝规则写入devices.deny文件,但device_a规则不完整
// WriteFile函数未在代码中定义,可能是自定义函数
ret = WriteFile(devicesDenyPath.c_str(), device_a.c_str()); // 写入拒绝规则(但规则可能不完整或无效)
ASSERT_NE(ret, -1); // 断言写入操作成功(返回值不为-1)
// 尝试以只读模式打开测试设备文件/dev/hi_mipi,并尝试创建(如果文件不存在)
// 但由于前面设置了拒绝规则(尽管不完整),预期打开操作会失败
fd = open(test_dev.c_str(), O_RDONLY|O_CREAT); // 尝试打开(并可能创建)/dev/hi_mipi设备文件,只读模式
// 断言打开操作失败(文件描述符为-1),因为设备被拒绝访问
ASSERT_EQ(fd, -1); // 断言打开文件操作失败
// 注意:这里的close调用是多余的,因为fd为-1,不是有效的文件描述符
// 但为了代码的整洁性和避免潜在警告,仍然保留(void)close(fd);
(void)close(fd); // 尝试关闭文件(但实际上是多余的)
// 尝试以只写模式打开测试设备文件/dev/hi_mipi,并尝试创建(如果文件不存在)
// 同样,由于前面设置了拒绝规则,预期打开操作会失败
fd = open(test_dev.c_str(), O_WRONLY|O_CREAT); // 尝试打开(并可能创建)/dev/hi_mipi设备文件,只写模式
// 断言打开操作失败(文件描述符为-1),因为设备被拒绝访问
ASSERT_EQ(fd, -1); // 断言打开文件操作失败
(void)close(fd); // 尝试关闭文件(但实际上是多余的)
// 尝试删除之前创建的目录
ret = rmdir(path.c_str()); // 删除/proc/plimits/test目录
ASSERT_EQ(ret, 0); // 断言删除目录操作成功(返回值为0)
}
7 months ago
Lvwenxuan
2d46693239
#include <cstdio> // 引入标准输入输出库
...
#include <unistd.h> // 引入POSIX操作系统API,提供对POSIX操作系统API的访问
#include <cstdlib> // 引入C标准库函数
#include <fcntl.h> // 引入文件控制选项,用于open等函数
#include <cstring> // 引入字符串操作函数
#include <gtest/gtest.h> // 引入Google Test框架,用于单元测试
#include "It_process_plimits.h" // 引入自定义头文件,可能包含测试所需的声明或定义
// 定义测试函数ItProcessPlimitsDevices001
void ItProcessPlimitsDevices001(void)
{
int fd; // 声明文件描述符变量
int ret; // 声明返回值变量
mode_t mode; // 声明文件模式变量(未初始化)
char writeBuf[8]; // 声明写入缓冲区,大小为8字节
std::string test_dev = "/dev/hi_mipi"; // 定义测试设备文件路径
std::string path = "/proc/plimits/test"; // 定义/proc/plimits/test目录路径
std::string procsTestPath = "/proc/plimits/test/plimits.procs"; // 定义进程限制文件路径
// 尝试创建目录,但mode未初始化,此处存在潜在问题
ret = mkdir(path.c_str(), S_IFDIR | mode); // S_IFDIR应为0(对于mkdir来说,通常只使用权限位)
ASSERT_EQ(ret, 0); // 断言创建目录操作成功
// 使用memset_s安全地清零writeBuf
(void)memset_s(writeBuf, sizeof(writeBuf), 0, sizeof(writeBuf));
// 将当前进程ID格式化为字符串并存储到writeBuf中
ret = sprintf_s(writeBuf, sizeof(writeBuf), "%d", getpid());
ASSERT_NE(ret, -1); // 断言格式化操作成功(非-1)
// 尝试将进程ID写入到plimits.procs文件中,但WriteFile函数未定义,可能是自定义函数
ret = WriteFile(procsTestPath.c_str(), writeBuf);
ASSERT_NE(ret, 0); // 断言写入操作失败(此处的断言逻辑可能需要根据WriteFile的实现调整)
// 尝试以读写和创建模式打开/dev/hi_mipi设备文件
fd = open(test_dev.c_str(), O_RDWR|O_CREAT);
ASSERT_NE(fd, -1); // 断言打开文件操作成功(文件描述符不为-1)
// 关闭文件描述符
(void)close(fd);
// 尝试删除之前创建的目录
ret = rmdir(path.c_str());
ASSERT_EQ(ret, 0); // 断言删除目录操作成功
}
7 months ago
wcr
2b84597fad
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
...
# Conflicts:
# kernel_liteos_a-master/testsuites/unittest/net/netdb/full/net_netdb_test_020.cpp
# kernel_liteos_a-master/testsuites/unittest/net/netdb/full/net_netdb_test_022.cpp
# kernel_liteos_a-master/testsuites/unittest/net/netdb/smoke/net_netdb_test_001.cpp
# kernel_liteos_a-master/testsuites/unittest/process/basic/pthread/process_pthread_test.cpp
7 months ago
wcr
ba78f4af13
123312
7 months ago
wcr
2bbd81e1bb
1231
7 months ago
Lvwenxuan
1e2e1722f8
/*
...
* 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.
*/
#ifndef _IT_PTHREAD_TEST_H // 防止头文件被重复包含
#define _IT_PTHREAD_TEST_H
#include "osTest.h" // 包含操作系统测试相关的头文件
#include <sys/resource.h> // 包含资源控制相关的头文件
#include <sys/wait.h> // 包含等待进程结束相关的头文件
#include <time.h> // 包含时间处理的头文件
#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) // 定义宏,用于睡眠和让出CPU,tick为微秒单位
#include "sys/syscall.h" // 包含系统调用相关的头文件
// 定义一个内联函数,用于执行系统调用
static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4)
{
register int reg7 __asm__("r7") = nbr; // 将系统调用号放入寄存器r7
register int reg3 __asm__("r3") = parm4; // 将第四个参数放入寄存器r3
register int reg2 __asm__("r2") = parm3; // 将第三个参数放入寄存器r2
register int reg1 __asm__("r1") = parm2; // 将第二个参数放入寄存器r1
register int reg0 __asm__("r0") = parm1; // 将第一个参数放入寄存器r0
// 使用svc指令触发系统调用,将结果存回reg0
__asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory");
return reg0; // 返回系统调用的结果
}
// 声明全局变量,用于存储单元测试的错误码和错误行号
extern INT32 g_iCunitErrCode;
extern INT32 g_iCunitErrLineNo;
// 声明一系列pthread相关的测试函数
extern void ItTestPthread001(void); // pthread测试函数1
extern void ItTestPthread002(void); // pthread测试函数2
extern void ItTestPthread003(void); // pthread测试函数3
extern void ItTestPthread004(void); // pthread测试函数4
extern void ItTestPthread005(void); // pthread测试函数5
extern void ItTestPthread006(void); // pthread测试函数6
extern void ItTestPthread007(void); // pthread测试函数7
extern void ItTestPthread008(void); // pthread测试函数8
extern void ItTestPthread009(void); // pthread测试函数9
extern void ItTestPthread010(void); // pthread测试函数10
extern void ItTestPthread012(void); // 省略了11,可能是个错误或者遗漏
extern void ItTestPthread011(void); // pthread测试函数11
extern void ItTestPthread013(void); // pthread测试函数13
extern void ItTestPthread014(void); // pthread测试函数14
extern void ItTestPthread015(void); // pthread测试函数15
extern void ItTestPthread016(void); // pthread测试函数16
extern void ItTestPthread017(void); // pthread测试函数17
extern void ItTestPthread018(void); // pthread测试函数18
extern void ItTestPthread019(void); // pthread测试函数19
extern void ItTestPthread020(void); // pthread测试函数20
extern void ItTestPthread021(void); // pthread测试函数21
extern void ItTestPthread022(void); // pthread测试函数22
extern void ItTestPthread023(void); // pthread测试函数23
extern void ItTestPthread024(void); // pthread测试函数24
extern void ItTestPthread025(void); // pthread测试函数25
extern void ItTestPthread026(void); // pthread测试函数26
extern void ItTestPthread027(void); // pthread测试函数27
extern void ItTestPthreadAtfork001(void); // pthread atfork测试函数1
extern void ItTestPthreadAtfork002(void); // pthread atfork测试函数2
extern void ItTestPthreadOnce001(void); // pthread once测试函数1
extern void ItTestPthreadCond001(void); // pthread 条件变量测试函数1
extern void ItTestPthreadCond002(void); // pthread 条件变量测试函数2
extern void ItTestPthreadCond003(void); // pthread 条件变量测试函数3
extern void ItTestPthreadCond004(void); // pthread 条件变量测试函数4
#endif // 结束头文件保护
7 months ago
Lvwenxuan
7a03be035e
/*
...
* 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 "pthread.h" // 引入POSIX线程库,用于多线程编程
#include "linux/capability.h" // 引入Linux能力(capabilities)定义,用于权限控制
#include <sys/capability.h> // 引入系统能力接口
#include "it_test_capability.h" // 假设是测试框架或测试相关的头文件
#include <signal.h> // 引入信号处理函数
#include <sys/types.h> // 引入基本数据类型
#include <time.h> // 引入时间处理函数
#define CAP_NUM 2 // 定义能力数组的大小
#define INVAILD_PID 65535 // 定义一个无效的进程ID
#define CHANGE_CHILD_UID 1000 // 定义子进程要更改的用户ID
// 信号处理函数,当前为空实现
static void Sigac(int param)
{
return;
}
// 子进程函数
static void Child()
{
int i = 10; // 循环计数器
signal(25, Sigac); // 设置信号25的处理函数为Sigac
while (i--) { // 循环10次,每次睡眠1秒
sleep(1);
}
// 睡眠10秒后退出
exit(0);
}
// 测试子进程的函数
static int TestChild(VOID)
{
struct __user_cap_header_struct capheader; // 定义能力头部结构体
struct __user_cap_data_struct capdata[CAP_NUM]; // 定义能力数据结构体数组
struct __user_cap_data_struct capdatac[CAP_NUM]; // 定义另一个能力数据结构体数组,用于获取当前能力
struct timespec tp; // 定义时间结构体
int ret; // 定义返回值变量,此处漏写了初始化
// 初始化结构体
(void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); // 清零能力头部结构体
(void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, CAP_NUM * sizeof(struct __user_cap_data_struct)); // 清零能力数据结构体数组
capdata[0].permitted = 0xffffffff; // 设置允许的所有能力为全开
capdata[1].permitted = 0xffffffff; // 同上,第二个数据结构体也全开(虽然只用一个)
capheader.version = _LINUX_CAPABILITY_VERSION_3; // 设置能力版本
// 设置能力的有效位
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); // 允许修改进程能力
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); // 允许改变用户ID
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); // 允许发送信号
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); // 允许改变系统时间
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); // 允许改变调度优先级
// 使用capset设置能力并检查返回值
ret = capset(&capheader, &capdata[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capset返回0,表示成功
ret = capget(&capheader, &capdatac[0]); // 获取当前能力
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capget返回0,表示成功
capheader.pid = INVAILD_PID; // 设置一个无效的PID
ret = capget(&capheader, &capdatac[0]); // 尝试获取无效PID的能力
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言返回-1,表示失败
errno = 0; // 重置errno
capheader.pid = 3; // 设置PID为3
kill(capheader.pid, 0); // 检查PID是否存在
if (errno != ESRCH) { // 如果PID存在
ret = capget(&capheader, &capdatac[0]); // 获取能力
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); // 打印有效和允许的能力
}
// 类似地,检查PID 4, 5, 6
errno = 0;
capheader.pid = 4;
kill(capheader.pid, 0);
if (errno != ESRCH) {
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted);
}
errno = 0;
capheader.pid = 5;
kill(capheader.pid, 0);
if (errno != ESRCH) {
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted);
}
errno = 0;
capheader.pid = 6;
kill(capheader.pid, 0);
if (errno != ESRCH) {
ret = capget(&capheader, &capdatac[0]);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted);
}
capheader.pid = 0; // 重置PID为0(当前进程)
// 尝试重置子进程的UID
int pid = fork(); // 创建子进程
if (pid == 0) { // 如果是子进程
ret = setuid(CHANGE_CHILD_UID); // 尝试改变用户ID
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
Child(); // 执行子进程函数
}
sleep(1); // 父进程等待1秒
ret = kill(pid, SIGXFSZ); // 尝试发送SIGXFSZ信号给子进程
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
// 移除KILL能力并再次尝试发送信号,应该失败
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_KILL);
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = kill(pid, SIGXFSZ); // 再次尝试发送信号
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败
// 尝试设置系统时间,应该成功然后失败(移除SYS_TIME能力)
tp.tv_sec = 0; // 设置时间为0
tp.tv_nsec = 0; // 纳秒部分也设置为0
ret = clock_settime(CLOCK_REALTIME, &tp); // 尝试设置时间
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); // 移除SYS_TIME能力
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = clock_settime(CLOCK_REALTIME, &tp); // 再次尝试设置时间
ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败
// 尝试改变子进程的调度优先级,应该成功然后失败(移除SYS_NICE能力)
struct sched_param param = { 0 }; // 定义调度参数结构体
ret = sched_getparam(pid, ¶m); // 获取当前调度参数
param.sched_priority--; // 降低优先级
ret = sched_setparam(pid, ¶m); // 尝试设置新的调度参数
ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功
capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); // 移除SYS_NICE能力
ret = capset(&capheader, &capdata[0]); // 更新能力
ret = sched_setparam(pid, ¶m); // 再次尝试设置调度参数
ICUNIT_ASSERT_EQUAL(ret, -1, ret);
wait(nullptr);
exit(92);
return 0;
}
static int TestCase(VOID)
{
int ret;
int status = 0;
pid_t pid = fork();
ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT);
if (pid == 0) {
ret = TestChild();
exit(__LINE__);
}
ret = waitpid(pid, &status, 0);
ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT);
status = WEXITSTATUS(status);
ICUNIT_GOTO_EQUAL(status, 92, status, EXIT);
return 0;
EXIT:
return 1;
}
void ItTestCap001(void)
{
TEST_ADD_CASE("IT_SEC_CAP_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION);
}
7 months ago
Mr.NaCl
c42d4c8f9c
read and commit It_process_plimits_008.cpp
7 months ago
赵颢翔
dafc1c8a0a
批注004
7 months ago
wcr
fa052b7a28
12283
7 months ago
wcr
d38443f8c2
12282
7 months ago
wcr
e885d4d491
12281
7 months ago
wcr
cc2f7154e9
1226
7 months ago
赵颢翔
5c9daabe2a
批注003
7 months ago
赵颢翔
faf14db68b
Merge branch 'main' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs
7 months ago
赵颢翔
8b314ac8fb
修改002
7 months ago
Mr.NaCl
a835bb28b1
read and commented
7 months ago
wcr
ad862c087c
13
7 months ago
wcr
e40ef14308
12
7 months ago
wcr
5ae7b2f1a6
Merge branch '分支昶' of https://bdgit.educoder.net/py6atlu3x/openharmonydocs into 分支昶
7 months ago
wcr
8367e625c7
12232
7 months ago
wcr
2c6af109bd
1223
7 months ago
赵颢翔
fd0ab82e14
上传
7 months ago
赵颢翔
7b80ec07b2
上传
7 months ago
赵颢翔
1b8e680a1b
修改1
7 months ago
赵颢翔
5492542b81
代码
7 months ago