实现了myshell, mysu

This commit is contained in:
lzy
2024-05-15 22:02:37 +08:00
parent 7d08b75eaa
commit 0ee62429a2
3 changed files with 177 additions and 11 deletions

View File

@@ -1,38 +1,95 @@
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#define DELIMS " \t\n"
struct cmd_st
{
glob_t globres;
};
static void prompt(void)
{
printf("mysh-0.1$ ");
}
/**
* @brief 解析命令行
* @details
* line 不加 const 是考虑以后可能加 alias 功能
*
* @param line
* @param res
*/
static void parse(char *line, struct cmd_st *res)
{
char *tok;
int i = 0;
//* 根据分隔符分割小串
// strtok();
while (1)
{
tok = strsep(&line, DELIMS);
if (NULL == tok)
break;
if ('\0' == tok[0]) // 判断是否为空串
continue;
// 用glob nocheck 来解析
// 用 i 来让第一次不追加
glob(tok, GLOB_NOCHECK | GLOB_APPEND * i, NULL, &res->globres);
i = 1;
}
}
int main(int argc, char **argv)
{
char *linebuf = NULL;
size_t linebuf_size = 0;
struct cmd_st cmd;
pid_t pid;
while (1)
{
prompt();
getline();
if (getline(&linebuf, &linebuf_size, stdin) < 0)
break;
parse();
parse(linebuf, &cmd);
if ()
if (0)
{
;
/* dosomething */
}
else // 外部命令
{
fork();
if (< 0)
pid = fork();
if (pid < 0)
{
;
perror("fork");
exit(1);
}
if (0 ==) // child
if (0 == pid) // child
{
execXX;
perror();
execvp(cmd.globres.gl_pathv[0], cmd.globres.gl_pathv);
perror("execvp");
exit(1);
}
else // parent
{
wait();
wait(NULL);
}
}
}

View File

@@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* @brief 实现一个简单的su命令
* @details
* Usage: mysu uid
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
if (argc < 3)
{
fprintf(stderr, "Usage: mysu uid");
exit(1);
}
pid_t pid;
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if (0 == pid)
{
// child process
setuid(atoi(argv[1]));
execvp(argv[2], argv + 2);
perror("execvp");
exit(1);
}
else // parent process
wait(NULL);
exit(0);
}
/**
* !!!
* 此时,执行./mysu 0 cat /etc/shadow 依旧没有权限
* su - 切换到 root 用户
* 通过
* chown root mysu && chmod u+s mysu 即可
* 再回到普通用户,执行./mysu 0 cat /etc/shadow 即可查看 shadow 文件
*/