--------------------------------------------------------
shabby_shell
--------------------------------------------------------
起名为 shabby_shell 是因为他太简单了 ...
·Init 函数
void Init()
{
int fd_stdin = open("/dev_tty0", O_RDWR);
assert(fd_stdin == 0);
int fd_stdout = open("/dev_tty0", O_RDWR);
assert(fd_stdout == 1);
printf("Init() is running ...\n");
/* extract `cmd.tar' */
untar("/cmd.tar");
char *tty_list[] = {"/dev_tty1", "/dev_tty2"};
int i;
for (i = 0; i < sizeof(tty_list) / sizeof(tty_list[0]); i++)
{
int pid = fork();
if (pid != 0)
{ /* parent process */
printf("[parent is running, child pid:%d]\n", pid);
}
else
{ /* child process */
printf("[child is running, pid:%d]\n", getpid());
close(fd_stdin);
close(fd_stdout);
shabby_shell(tty_list[i]);
assert(0);
}
}
while (1)
{
int s;
int child = wait(&s);
printf("child (%d) exited with status: %d.\n", child, s);
}
assert(0);
}
——在 fork 之后,如果是父进程,接着 fork 下一个 shell 或者退出循环循环为每个子进程提供 wait 服务,如果是子进程,阻塞在 shabby_shell 执行 shell!
·shabby_shell 函数
void shabby_shell(const char *tty_name)
{
int fd_stdin = open(tty_name, O_RDWR);
assert(fd_stdin == 0);
int fd_stdout = open(tty_name, O_RDWR);
assert(fd_stdout == 1);
char rdbuf[128];
while (1)
{
write(1, "$ ", 2);
int r = read(0, rdbuf, 70);
rdbuf[r] = 0;
int argc = 0;
char *argv[PROC_ORIGIN_STACK];
char *p = rdbuf;
char *s;
int word = 0;
char ch;
do /* 解析输入的字符串,拆分字符串,构造字符串指针数组 */
{
ch = *p;
if (*p != ' ' && *p != 0 && !word)
{
s = p;
word = 1;
}
if ((*p == ' ' || *p == 0) && word)
{
word = 0;
argv[argc++] = s;
*p = 0;
}
p++;
} while (ch);
argv[argc] = 0; /* 最后的 0 参数 */
int fd = open(argv[0], O_RDWR); /* 打开子程序文件 */
if (fd == -1)
{
if (rdbuf[0])
{
write(1, "{", 1);
write(1, rdbuf, r);
write(1, "}\n", 2);
}
}
else
{
close(fd);
int pid = fork();
if (pid != 0)
{ /* parent */
int s;
wait(&s);
}
else
{ /* child */
execv(argv[0], argv);
}
}
}
close(1);
close(0);
}
——遇见正确的命令,fork + exec + exit 一遍,这一趟回来之后继续执行 shell !
运行
OK,Happy birthday to Tinix !!!