fix: 修复前后台进程支持
1.优化shell机制,删除无用的线程 2.修复前后台进程支持 Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: I8bb13e53f290989455260dd5fb3f604ddebc9c8b
This commit is contained in:
parent
fa0e803ac9
commit
338044cd9c
|
@ -32,13 +32,15 @@
|
||||||
#ifndef _SHELL_PRI_H
|
#ifndef _SHELL_PRI_H
|
||||||
#define _SHELL_PRI_H
|
#define _SHELL_PRI_H
|
||||||
|
|
||||||
|
#include "shell.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
extern void *ShellEntry(void *argv);
|
extern void ShellEntry(ShellCB *shellCB);
|
||||||
extern void *ShellTask(void *argv);
|
extern void *ShellTask(void *argv);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#ifndef _SHMSG_H
|
#ifndef _SHMSG_H
|
||||||
#define _SHMSG_H
|
#define _SHMSG_H
|
||||||
|
|
||||||
|
#include "shell_list.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -61,8 +62,7 @@ extern "C" {
|
||||||
|
|
||||||
typedef void (* OutputFunc)(const char *fmt, ...);
|
typedef void (* OutputFunc)(const char *fmt, ...);
|
||||||
extern int ShellTaskInit(ShellCB *shellCB);
|
extern int ShellTaskInit(ShellCB *shellCB);
|
||||||
extern int ShellEntryInit(ShellCB *shellCB);
|
extern void ChildExec(const char *cmdName, char *const paramArray[], bool foreground);
|
||||||
extern void ChildExec(const char *cmdName, char *const paramArray[]);
|
|
||||||
extern void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB);
|
extern void ShellCmdLineParse(char c, OutputFunc outputFunc, ShellCB *shellCB);
|
||||||
extern int ShellNotify(ShellCB *shellCB);
|
extern int ShellNotify(ShellCB *shellCB);
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,16 @@
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
#include "show.h"
|
#include "show.h"
|
||||||
#include "shmsg.h"
|
#include "shmsg.h"
|
||||||
#include "shcmd.h"
|
#include "shcmd.h"
|
||||||
|
#include "shell_pri.h"
|
||||||
#include "semaphore.h"
|
#include "semaphore.h"
|
||||||
#include "securec.h"
|
#include "securec.h"
|
||||||
#include "unistd.h"
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
|
|
||||||
ShellCB *g_shellCB = NULL;
|
ShellCB *g_shellCB = NULL;
|
||||||
|
|
||||||
|
@ -77,13 +80,8 @@ static int OsShellCreateTask(ShellCB *shellCB)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ShellEntryInit(shellCB);
|
shellCB->shellEntryHandle = pthread_self();
|
||||||
if (ret != SH_OK) {
|
return 0;
|
||||||
goto OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)pthread_join(shellCB->shellTaskHandle, NULL);
|
|
||||||
(void)pthread_join(shellCB->shellEntryHandle, NULL);
|
|
||||||
|
|
||||||
OUT:
|
OUT:
|
||||||
ShellDeinit(shellCB);
|
ShellDeinit(shellCB);
|
||||||
|
@ -98,7 +96,7 @@ static int DoShellExec(char **argv)
|
||||||
char *cmdLine = NULL;
|
char *cmdLine = NULL;
|
||||||
|
|
||||||
if (strncmp(argv[0], SHELL_EXEC_COMMAND, SHELL_EXEC_COMMAND_BYTES) == 0) {
|
if (strncmp(argv[0], SHELL_EXEC_COMMAND, SHELL_EXEC_COMMAND_BYTES) == 0) {
|
||||||
ChildExec(argv[1], argv + 1);
|
ChildExec(argv[1], argv + 1, FALSE);
|
||||||
}
|
}
|
||||||
for (i = 0; argv[i]; i++) {
|
for (i = 0; argv[i]; i++) {
|
||||||
len += strlen(argv[i]);
|
len += strlen(argv[i]);
|
||||||
|
@ -125,11 +123,22 @@ static int DoShellExec(char **argv)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ShellSigChildHook(int sig)
|
||||||
|
{
|
||||||
|
(void)sig;
|
||||||
|
|
||||||
|
while (waitpid(-1, NULL, WNOHANG) > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret = SH_NOK;
|
int ret = SH_NOK;
|
||||||
ShellCB *shellCB = NULL;
|
ShellCB *shellCB = NULL;
|
||||||
|
|
||||||
|
(void)signal(SIGCHLD, ShellSigChildHook);
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
ret = DoShellExec(argv + 1);
|
ret = DoShellExec(argv + 1);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -165,7 +174,12 @@ int main(int argc, char **argv)
|
||||||
sem_init(&shellCB->shellSem, 0, 0);
|
sem_init(&shellCB->shellSem, 0, 0);
|
||||||
|
|
||||||
g_shellCB = shellCB;
|
g_shellCB = shellCB;
|
||||||
return OsShellCreateTask(shellCB);
|
ret = OsShellCreateTask(shellCB);
|
||||||
|
if (ret != SH_OK) {
|
||||||
|
goto ERR_OUT3;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellEntry(shellCB);
|
||||||
|
|
||||||
ERR_OUT3:
|
ERR_OUT3:
|
||||||
(void)pthread_mutex_destroy(&shellCB->historyMutex);
|
(void)pthread_mutex_destroy(&shellCB->historyMutex);
|
||||||
|
|
|
@ -351,7 +351,7 @@ char *GetCmdName(const char *cmdline, unsigned int len)
|
||||||
return cmdName;
|
return cmdName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChildExec(const char *cmdName, char *const paramArray[])
|
void ChildExec(const char *cmdName, char *const paramArray[], bool foreground)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
pid_t gid;
|
pid_t gid;
|
||||||
|
@ -367,10 +367,12 @@ void ChildExec(const char *cmdName, char *const paramArray[])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tcsetpgrp(STDIN_FILENO, gid);
|
if (!foreground) {
|
||||||
if (ret != 0) {
|
ret = tcsetpgrp(STDIN_FILENO, gid);
|
||||||
printf("tcsetpgrp failed, errno %d\n", errno);
|
if (ret != 0) {
|
||||||
exit(1);
|
printf("tcsetpgrp failed, errno %d\n", errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = execve(cmdName, paramArray, NULL);
|
ret = execve(cmdName, paramArray, NULL);
|
||||||
|
@ -404,20 +406,30 @@ int CheckExit(const char *cmdName, const CmdParsed *cmdParsed)
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, const CmdParsed *cmdParsed)
|
static void DoCmdExec(const char *cmdName, const char *cmdline, unsigned int len, CmdParsed *cmdParsed)
|
||||||
{
|
{
|
||||||
|
bool foreground = FALSE;
|
||||||
int ret;
|
int ret;
|
||||||
pid_t forkPid;
|
pid_t forkPid;
|
||||||
|
|
||||||
if (strncmp(cmdline, CMD_EXEC_COMMAND, CMD_EXEC_COMMAND_BYTES) == 0) {
|
if (strncmp(cmdline, CMD_EXEC_COMMAND, CMD_EXEC_COMMAND_BYTES) == 0) {
|
||||||
|
if ((cmdParsed->paramCnt > 1) && (strcmp(cmdParsed->paramArray[cmdParsed->paramCnt - 1], "&") == 0)) {
|
||||||
|
free(cmdParsed->paramArray[cmdParsed->paramCnt - 1]);
|
||||||
|
cmdParsed->paramArray[cmdParsed->paramCnt - 1] = NULL;
|
||||||
|
cmdParsed->paramCnt--;
|
||||||
|
foreground = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
forkPid = fork();
|
forkPid = fork();
|
||||||
if (forkPid < 0) {
|
if (forkPid < 0) {
|
||||||
printf("Faild to fork from shell\n");
|
printf("Faild to fork from shell\n");
|
||||||
return;
|
return;
|
||||||
} else if (forkPid == 0) {
|
} else if (forkPid == 0) {
|
||||||
ChildExec(cmdParsed->paramArray[0], cmdParsed->paramArray);
|
ChildExec(cmdParsed->paramArray[0], cmdParsed->paramArray, foreground);
|
||||||
} else {
|
} else {
|
||||||
waitpid(forkPid, 0, 0);
|
if (!foreground) {
|
||||||
|
(void)waitpid(forkPid, 0, 0);
|
||||||
|
}
|
||||||
ret = tcsetpgrp(STDIN_FILENO, getpid());
|
ret = tcsetpgrp(STDIN_FILENO, getpid());
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("tcsetpgrp failed, errno %d\n", errno);
|
printf("tcsetpgrp failed, errno %d\n", errno);
|
||||||
|
@ -567,20 +579,10 @@ static void ExecCmdline(const char *cmdline)
|
||||||
free(output);
|
free(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecycleZombieChild(void)
|
|
||||||
{
|
|
||||||
while (waitpid(-1, NULL, WNOHANG) > 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ShellCmdProcess(ShellCB *shellCB)
|
static void ShellCmdProcess(ShellCB *shellCB)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* recycle zombine child process */
|
char *buf = GetCmdline(shellCB);
|
||||||
RecycleZombieChild();
|
|
||||||
buf = GetCmdline(shellCB);
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -654,25 +656,19 @@ static int ShellKernelReg(unsigned int shellHandle)
|
||||||
return ioctl(STDIN_FILENO, CONSOLE_CONTROL_REG_USERTASK, shellHandle);
|
return ioctl(STDIN_FILENO, CONSOLE_CONTROL_REG_USERTASK, shellHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ShellEntry(void *argv)
|
void ShellEntry(ShellCB *shellCB)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
int ret;
|
int ret;
|
||||||
int n;
|
int n;
|
||||||
pid_t tid = syscall(__NR_gettid);
|
pid_t tid = syscall(__NR_gettid);
|
||||||
ShellCB *shellCB = (ShellCB *)argv;
|
|
||||||
|
|
||||||
if (shellCB == NULL) {
|
if (shellCB == NULL) {
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);
|
(void)memset_s(shellCB->shellBuf, SHOW_MAX_LEN, 0, SHOW_MAX_LEN);
|
||||||
|
|
||||||
ret = prctl(PR_SET_NAME, "ShellEntry");
|
|
||||||
if (ret != SH_OK) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ShellKernelReg((int)tid);
|
ret = ShellKernelReg((int)tid);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("another shell is already running!\n");
|
printf("another shell is already running!\n");
|
||||||
|
@ -685,32 +681,5 @@ void *ShellEntry(void *argv)
|
||||||
ShellCmdLineParse(ch, (OutputFunc)printf, shellCB);
|
ShellCmdLineParse(ch, (OutputFunc)printf, shellCB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ShellEntryInit(ShellCB *shellCB)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
size_t stackSize = SHELL_ENTRY_STACKSIZE;
|
|
||||||
void *arg = NULL;
|
|
||||||
pthread_attr_t attr;
|
|
||||||
|
|
||||||
if (shellCB == NULL) {
|
|
||||||
return SH_NOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pthread_attr_init(&attr);
|
|
||||||
if (ret != SH_OK) {
|
|
||||||
return SH_NOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_setstacksize(&attr, stackSize);
|
|
||||||
arg = (void *)shellCB;
|
|
||||||
ret = pthread_create(&shellCB->shellEntryHandle, &attr, &ShellEntry, arg);
|
|
||||||
if (ret != SH_OK) {
|
|
||||||
return SH_NOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue