feat: 支持killpg和waitid
killpg:给进程组发信号 waitid:等待进程结束 修改测试用例到full里面 Change-Id: Ice058ab4a6eede8ecbaacea0894c2161e3b9dce2 Signed-off-by: wjj <502004968@qq.com>
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user