🦄 refactor(C14, C15):

This commit is contained in:
lzy
2024-05-16 21:57:14 +08:00
parent 60d670d130
commit b66e536177
34 changed files with 2 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/**
* @brief data +%s
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
puts("Begin!");
fflush(NULL); // !!!
execl("/bin/date", "date", "+%s", NULL);
// NULL 作为参数列表的结束标志
// !! 如果不出错,不会到这里
perror("execl()");
exit(1);
puts("End!");
exit(0);
}

View File

@@ -0,0 +1,42 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* @brief few: folk, execl, wait
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
pid_t pid;
puts("Begin!");
fflush(NULL);
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (0 == pid) // child
{
execl("/bin/date", "date", "+%s", NULL);
perror("execl()");
exit(1);
}
wait(NULL);
puts("End!");
exit(0);
}

View File

@@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
pid_t pid;
/*
* 如果 ./fork1 > /tmp/out
* begin会由父进程输出两次
* 缓冲问题
* 文件时全缓冲
*/
printf("[%d]Begin!\n", getpid());
fflush(NULL); // !!! 在fork之前刷新该刷新的流
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0) // child
{
printf("[%d]Child is working!\n", getpid());
}
else // parent
{
printf("[%d]Parent is working!\n", getpid());
}
printf("[%d]End!\n", getpid());
// getchar();
exit(0);
}

View File

@@ -0,0 +1,83 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <syslog.h>
#include <time.h>
#include <unistd.h>
#define FNAME "/tmp/out"
static int deamonize(void)
{
pid_t pid;
int fd;
pid = fork();
if (pid < 0)
return -1;
if (pid > 0) // parent process
exit(0);
fd = open("/dev/null", O_RDWR);
if (fd < 0)
return -1;
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
if (fd > 2)
close(fd);
setsid();
chdir("/"); // 防止一直占用某设备
// umask(0);
return 0;
}
int main(int argc, char **argv)
{
FILE *fp;
int i;
openlog("mydaemon", LOG_PID, LOG_DAEMON);
if (deamonize())
{
syslog(LOG_ERR, "daemonize() failed!");
exit(1);
}
else
{
syslog(LOG_INFO, "daemonize() success!");
}
fp = fopen(FNAME, "w");
if (fp == NULL)
{
syslog(LOG_ERR, "fopen() failed!: %s", strerror(errno));
exit(1);
}
syslog(LOG_INFO, "%s was opened successfully!", FNAME);
for (i = 0;; i++)
{
fprintf(fp, "%d\n", i);
fflush(fp); //! 刷新缓冲区
syslog(LOG_DEBUG, "%d is printed", i);
sleep(1);
}
// 目前守护进程只能异常终止,下面其实无法执行到
fclose(fp);
closelog();
exit(0);
}

View File

@@ -0,0 +1,98 @@
#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();
if (getline(&linebuf, &linebuf_size, stdin) < 0)
break;
parse(linebuf, &cmd);
if (0)
{
/* dosomething */
}
else // 外部命令
{
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if (0 == pid) // child
{
execvp(cmd.globres.gl_pathv[0], cmd.globres.gl_pathv);
perror("execvp");
exit(1);
}
else // parent
{
wait(NULL);
}
}
}
exit(0);
}

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 文件
*/

View File

@@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define LEFT 30000000
#define RIGHT 30000200
/**
* @brief 求质数(单机版)
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
int i, j, mark;
for (i = LEFT; i <= RIGHT; i++)
{
mark = 1;
for (j = 2; j < i / 2; j++)
{
if (i % j == 0)
{
mark = 0;
break;
}
}
if (mark)
printf("%d is a primer\n", i);
}
exit(0);
}

View File

@@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define LEFT 30000000
#define RIGHT 30000200
/**
* @brief 求质数(多进程版)
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
int i, j, mark;
pid_t pid;
for (i = LEFT; i <= RIGHT; i++)
{
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0) // child
{
mark = 1;
for (j = 2; j < i / 2; j++)
{
if (i % j == 0)
{
mark = 0;
break;
}
}
if (mark)
printf("%d is a primer\n", i);
sleep(1000); // * 让父进程先结束
exit(0); // ! 退出子进程
// ! init 在孤儿进程 exit 后才收尸
}
}
// sleep(1000); // * 让子进程先结束,子进程会变成僵尸态
exit(0);
}

View File

@@ -0,0 +1,56 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define LEFT 30000000
#define RIGHT 30000200
/**
* @brief 求质数(多进程版)
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
int i, j, mark;
pid_t pid;
for (i = LEFT; i <= RIGHT; i++)
{
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (pid == 0) // child
{
mark = 1;
for (j = 2; j < i / 2; j++)
{
if (i % j == 0)
{
mark = 0;
break;
}
}
if (mark)
printf("%d is a primer\n", i);
exit(0); // ! 退出子进程
}
}
// int st;
for (i = LEFT; i <= RIGHT; i++)
// wait(&st);
wait(NULL);
exit(0);
}

View File

@@ -0,0 +1,59 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define LEFT 30000000
#define RIGHT 30000200
#define N 3
/**
* @brief 求质数(多进程版)
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
int i, j, n, mark;
pid_t pid;
for (n = 0; n < N; n++)
{
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1); // ! 加入在第三次fork失败时退出前两次没有收尸
}
if (pid == 0)
{
for (i = LEFT + n; i <= RIGHT; i += N)
{
mark = 1;
for (j = 2; j < i / 2; j++)
{
if (i % j == 0)
{
mark = 0;
break;
}
}
if (mark)
printf("[%d]%d is a primer\n", n, i);
}
exit(0); // ! 退出子进程
}
}
for (n = 0; n < N; n++)
wait(NULL);
exit(0);
}

View File

@@ -0,0 +1,45 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* @brief few: folk, execl, wait
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
pid_t pid;
puts("Begin!");
fflush(NULL);
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (0 == pid) // child
{
// execl("/bin/sleep", "sleep", "100", NULL);
execl("/bin/sleep", "httpd", "100", NULL);
// ! 低级木马进程树里看到的是httpd 100
perror("execl()");
exit(1);
}
wait(NULL);
puts("End!");
exit(0);
}

View File

@@ -0,0 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
system("date +%s > /tmp/out");
exit(0);
}

View File

@@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
/**
* @brief few: folk, execl, wait
* @details
*
* @param argc
* @param argv
* @return int
*/
int main(int argc, char **argv)
{
pid_t pid;
fflush(NULL);
pid = fork();
if (pid < 0)
{
perror("fork()");
exit(1);
}
if (0 == pid) // child
{
execl("/bin/sh", "sh", "-c", "date +%s", NULL);
perror("execl()");
exit(1);
}
wait(NULL);
exit(0);
}