feat: 支持killpg和waitid

killpg:给进程组发信号
waitid:等待进程结束
修改测试用例到full里面

Change-Id: Ice058ab4a6eede8ecbaacea0894c2161e3b9dce2
Signed-off-by: wjj <502004968@qq.com>
This commit is contained in:
wjj
2021-08-12 16:16:33 +08:00
parent bbdb977b5e
commit dc3cc094a7
14 changed files with 279 additions and 78 deletions

View File

@@ -133,6 +133,59 @@ STATIC ProcessGroup *OsFindProcessGroup(UINT32 gid)
return NULL;
}
STATIC INT32 OsSendSignalToSpecifyProcessGroup(ProcessGroup *group, siginfo_t *info, INT32 permission)
{
INT32 ret, success, err;
LosProcessCB *childCB = NULL;
success = 0;
ret = -LOS_ESRCH;
LOS_DL_LIST_FOR_EACH_ENTRY(childCB, &(group->processList), LosProcessCB, subordinateGroupList) {
if (childCB->processID == 0) {
continue;
}
err = OsDispatch(childCB->processID, info, permission);
success |= !err;
ret = err;
}
/* At least one success. */
return success ? LOS_OK : ret;
}
LITE_OS_SEC_TEXT INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission)
{
INT32 ret, success, err;
ProcessGroup *group = NULL;
success = 0;
err = OsSendSignalToSpecifyProcessGroup(g_processGroup, info, permission);
success |= !err;
ret = err;
/* all processes group */
LOS_DL_LIST_FOR_EACH_ENTRY(group, &g_processGroup->groupList, ProcessGroup, groupList) {
/* all processes in the process group. */
err = OsSendSignalToSpecifyProcessGroup(group, info, permission);
success |= !err;
ret = err;
}
return success ? LOS_OK : ret;
}
LITE_OS_SEC_TEXT INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission)
{
ProcessGroup *group = NULL;
/* Send SIG to all processes in process group PGRP.
If PGRP is zero, send SIG to all processes in
the current process's process group. */
group = OsFindProcessGroup(pid ? -pid : LOS_GetCurrProcessGroupID());
if (group == NULL) {
return -LOS_ESRCH;
}
/* all processes in the process group. */
return OsSendSignalToSpecifyProcessGroup(group, info, permission);
}
STATIC LosProcessCB *OsFindGroupExitProcess(ProcessGroup *group, INT32 pid)
{
LosProcessCB *childCB = NULL;
@@ -1006,12 +1059,19 @@ WAIT_BACK:
return LOS_OK;
}
STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status)
STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intSave, INT32 *status, siginfo_t *info)
{
ProcessGroup *group = NULL;
UINT32 pid = childCB->processID;
UINT16 mode = childCB->processMode;
INT32 exitCode = childCB->exitCode;
UINT32 uid = 0;
#ifdef LOSCFG_SECURITY_CAPABILITY
if (childCB->user != NULL) {
uid = childCB->user->userID;
}
#endif
OsRecycleZombiesProcess((LosProcessCB *)childCB, &group);
SCHEDULER_UNLOCK(intSave);
@@ -1023,7 +1083,33 @@ STATIC UINT32 OsWaitRecycleChildProcess(const LosProcessCB *childCB, UINT32 intS
*status = exitCode;
}
}
/* get signal info */
if (info != NULL) {
siginfo_t tempinfo = { 0 };
tempinfo.si_signo = SIGCHLD;
tempinfo.si_errno = 0;
tempinfo.si_pid = pid;
tempinfo.si_uid = uid;
/*
* Process exit code
* 31 15 8 7 0
* | | exit code | core dump | signal |
*/
if ((exitCode & 0x7f) == 0) {
tempinfo.si_code = CLD_EXITED;
tempinfo.si_status = (exitCode >> 8U);
} else {
tempinfo.si_code = (exitCode & 0x80) ? CLD_DUMPED : CLD_KILLED;
tempinfo.si_status = (exitCode & 0x7f);
}
if (mode == OS_USER_MODE) {
(VOID)LOS_ArchCopyToUser((VOID *)(info), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
} else {
(VOID)memcpy_s((VOID *)(info), sizeof(siginfo_t), (const VOID *)(&(tempinfo)), sizeof(siginfo_t));
}
}
(VOID)LOS_MemFree(m_aucSysMem1, group);
return pid;
}
@@ -1057,7 +1143,7 @@ STATIC UINT32 OsWaitOptionsCheck(UINT32 options)
return LOS_OK;
}
LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
STATIC INT32 OsWait(INT32 pid, USER INT32 *status, USER siginfo_t *info, UINT32 options, VOID *rusage)
{
(VOID)rusage;
UINT32 ret;
@@ -1066,11 +1152,6 @@ LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, V
LosProcessCB *processCB = NULL;
LosTaskCB *runTask = NULL;
ret = OsWaitOptionsCheck(options);
if (ret != LOS_OK) {
return -ret;
}
SCHEDULER_LOCK(intSave);
processCB = OsCurrProcessGet();
runTask = OsCurrTaskGet();
@@ -1082,7 +1163,7 @@ LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, V
}
if (childCB != NULL) {
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status);
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
}
if ((options & LOS_WAIT_WNOHANG) != 0) {
@@ -1105,13 +1186,64 @@ LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, V
goto ERROR;
}
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status);
return (INT32)OsWaitRecycleChildProcess(childCB, intSave, status, info);
ERROR:
SCHEDULER_UNLOCK(intSave);
return pid;
}
LITE_OS_SEC_TEXT INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage)
{
(VOID)rusage;
UINT32 ret;
ret = OsWaitOptionsCheck(options);
if (ret != LOS_OK) {
return -ret;
}
return OsWait(pid, status, NULL, options, NULL);
}
STATIC UINT32 OsWaitidOptionsCheck(UINT32 options)
{
UINT32 flag = LOS_WAIT_WNOHANG | LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WEXITED | LOS_WAIT_WNOWAIT;
flag = ~flag & options;
if ((flag != 0) || (options == 0)) {
return LOS_EINVAL;
}
/*
* only support LOS_WAIT_WNOHANG | LOS_WAIT_WEXITED
* notsupport LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT
*/
if ((options & (LOS_WAIT_WSTOPPED | LOS_WAIT_WCONTINUED | LOS_WAIT_WNOWAIT)) != 0) {
return LOS_EOPNOTSUPP;
}
if (OS_INT_ACTIVE) {
return LOS_EINTR;
}
return LOS_OK;
}
LITE_OS_SEC_TEXT INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage)
{
(VOID)rusage;
UINT32 ret;
/* check options value */
ret = OsWaitidOptionsCheck(options);
if (ret != LOS_OK) {
return -ret;
}
return OsWait(pid, NULL, info, options, NULL);
}
STATIC UINT32 OsSetProcessGroupCheck(const LosProcessCB *processCB, UINT32 gid)
{
LosProcessCB *runProcessCB = OsCurrProcessGet();

View File

@@ -408,6 +408,12 @@ STATIC INLINE User *OsCurrUserGet(VOID)
* if this option is not specified.
*/
#define LOS_WAIT_WUNTRACED (1 << 1U)
#define LOS_WAIT_WSTOPPED (1 << 1U)
/*
* Wait for exited processes
*/
#define LOS_WAIT_WEXITED (1 << 2U)
/*
* return if a stopped child has been resumed by delivery of SIGCONT.
@@ -415,6 +421,12 @@ STATIC INLINE User *OsCurrUserGet(VOID)
*/
#define LOS_WAIT_WCONTINUED (1 << 3U)
/*
* Leave the child in a waitable state;
* a later wait call can be used to again retrieve the child status information.
*/
#define LOS_WAIT_WNOWAIT (1 << 24U)
/*
* Indicates that you are already in a wait state
*/
@@ -464,6 +476,8 @@ extern UINT32 OsGetKernelInitProcessID(VOID);
extern VOID OsSetSigHandler(UINTPTR addr);
extern UINTPTR OsGetSigHandler(VOID);
extern VOID OsWaitWakeTask(LosTaskCB *taskCB, UINT32 wakePID);
extern INT32 OsSendSignalToProcessGroup(INT32 pid, siginfo_t *info, INT32 permission);
extern INT32 OsSendSignalToAllProcess(siginfo_t *info, INT32 permission);
#ifdef __cplusplus
#if __cplusplus

View File

@@ -351,6 +351,10 @@ static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
int OsDispatch(pid_t pid, siginfo_t *info, int permission)
{
if (OsProcessIDUserCheckInvalid(pid) || pid < 0) {
return -ESRCH;
}
LosProcessCB *spcb = OS_PCB_FROM_PID(pid);
if (OsProcessIsUnused(spcb)) {
return -ESRCH;
@@ -382,20 +386,27 @@ int OsKill(pid_t pid, int sig, int permission)
int ret;
/* Make sure that the para is valid */
if (!GOOD_SIGNO(sig) || pid < 0) {
if (!GOOD_SIGNO(sig)) {
return -EINVAL;
}
if (OsProcessIDUserCheckInvalid(pid)) {
return -ESRCH;
}
/* Create the siginfo structure */
info.si_signo = sig;
info.si_code = SI_USER;
info.si_value.sival_ptr = NULL;
/* Send the signal */
ret = OsDispatch(pid, &info, permission);
if (pid > 0) {
/* Send the signal to the specify process */
ret = OsDispatch(pid, &info, permission);
} else if (pid == -1) {
/* Send SIG to all processes */
ret = OsSendSignalToAllProcess(&info, permission);
} else {
/* Send SIG to all processes in process group PGRP.
If PGRP is zero, send SIG to all processes in
the current process's process group. */
ret = OsSendSignalToProcessGroup(pid, &info, permission);
}
return ret;
}

View File

@@ -33,6 +33,7 @@
#define _LOS_PROCESS_H
#include "los_task.h"
#include <signal.h>
#ifdef LOSCFG_FS_VFS
#include "fs/fd_table.h"
@@ -58,6 +59,8 @@ extern UINT32 LOS_GetCurrProcessID(VOID);
extern INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage);
extern INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage);
extern INT32 LOS_GetCurrProcessGroupID(VOID);
extern INT32 LOS_GetProcessGroupID(UINT32 pid);