连接service进行报错信息上传,分离输出stderr和stdout

This commit is contained in:
Pan Qiancheng 2025-04-12 19:35:11 +08:00
parent e03d112d7a
commit 0d67b1acae
33 changed files with 539 additions and 262 deletions

View File

@ -24,7 +24,9 @@
"stdbool.h": "c", "stdbool.h": "c",
"stat.h": "c", "stat.h": "c",
"debug.h": "c", "debug.h": "c",
"types.h": "c" "types.h": "c",
"client.h": "c",
"limits.h": "c"
}, },
"C_Cpp.errorSquiggles": "disabled" "C_Cpp.errorSquiggles": "disabled"
} }

BIN
build/client.o Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,119 +1,8 @@
[Thu Apr 10 13:38:46 2025 [Sat Apr 12 16:24:43 2025
] Command: /bin/lesspipe
arg[0]: lesspipe
[Thu Apr 10 13:38:46 2025
] Command: /bin/dircolors
arg[0]: dircolors
arg[1]: -b
[Thu Apr 10 13:38:48 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
arg[2]: -CF
[Thu Apr 10 13:38:57 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
[Thu Apr 10 13:39:06 2025
] Command: /usr/lib/command-not-found
arg[0]: /usr/lib/command-not-found
arg[1]: --
arg[2]: nvidia-smi
[Thu Apr 10 13:39:26 2025
] Command: /bin/rm
arg[0]: rm
[Thu Apr 10 13:39:30 2025
] Command: /bin/rm
arg[0]: rm
arg[1]: -rf
arg[2]: ./Makefile
arg[3]: ./README.md
arg[4]: ./build
arg[5]: ./config
arg[6]: ./logs
arg[7]: ./output.txt
arg[8]: ./src
arg[9]: ./test_bash.sh
arg[10]: ./tests
[Thu Apr 10 13:40:41 2025
] Command: /bin/lesspipe
arg[0]: lesspipe
[Thu Apr 10 13:40:41 2025
] Command: /bin/dircolors
arg[0]: dircolors
arg[1]: -b
[Thu Apr 10 13:40:48 2025
] Command: /home/qcqcqc/miniconda3/bin/python ] Command: /home/qcqcqc/miniconda3/bin/python
arg[0]: python arg[0]: python
[Thu Apr 10 13:41:01 2025 arg[1]: -r
] Command: /home/qcqcqc/miniconda3/bin/pip [Sat Apr 12 16:25:59 2025
arg[0]: pip ] Command: /home/qcqcqc/miniconda3/bin/python
arg[1]: install arg[0]: python
arg[2]: abcdefaaaaa arg[1]: -r
[Thu Apr 10 16:50:23 2025
] Command: /bin/lesspipe
arg[0]: lesspipe
[Thu Apr 10 16:50:23 2025
] Command: /bin/dircolors
arg[0]: dircolors
arg[1]: -b
[Thu Apr 10 16:50:25 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
[Thu Apr 10 16:50:25 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
arg[2]: -CF
[Sat Apr 12 10:04:23 2025
] Command: /bin/lesspipe
arg[0]: lesspipe
[Sat Apr 12 10:04:23 2025
] Command: /bin/dircolors
arg[0]: dircolors
arg[1]: -b
[Sat Apr 12 10:04:26 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
arg[2]: -CF
[Sat Apr 12 10:04:43 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
[Sat Apr 12 10:06:47 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
[Sat Apr 12 10:08:51 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
arg[2]: -CF
[Sat Apr 12 10:08:52 2025
] Command: /bin/ls
arg[0]: ls
arg[1]: --color=auto
[Sat Apr 12 10:14:16 2025
] Command: /home/qcqcqc/miniconda3/bin/pip
arg[0]: pip
arg[1]: install
arg[2]: torch
[Sat Apr 12 10:41:47 2025
] Command: /home/qcqcqc/miniconda3/bin/pip
arg[0]: pip
arg[1]: install
arg[2]: torch
[Sat Apr 12 10:41:56 2025
] Command: /home/qcqcqc/miniconda3/bin/pip
arg[0]: pip
arg[1]: install
arg[2]: torch
arg[3]: abglpkhnjokb
[Sat Apr 12 10:43:13 2025
] Command: /home/qcqcqc/miniconda3/bin/pip
arg[0]: pip
arg[1]: install
arg[2]: torch
arg[3]: abglpkhnjokb

View File

@ -1,49 +0,0 @@
[DEBUG][PID 176170] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 176170] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build/ config/ logs/ output.txt src/ test_bash.sh* tests/
[DEBUG][PID 176315] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 176315] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build config logs output.txt src test_bash.sh tests
[DEBUG][PID 177976] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 177976] src/pty_dup.c:50:dupIO(): Child process ready.
Python 3.12.9 | packaged by Anaconda, Inc. | (main, Feb 6 2025, 18:56:27) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> [DEBUG][PID 178205] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 178205] src/pty_dup.c:50:dupIO(): Child process ready.
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
ERROR: Could not find a version that satisfies the requirement abcdefaaaaa (from versions: none)
ERROR: No matching distribution found for abcdefaaaaa
 [DEBUG][PID 458319] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 458319] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build config logs output.txt src test_bash.sh tests
[DEBUG][PID 458327] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 458327] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build/ config/ logs/ output.txt src/ test_bash.sh* tests/
Welcome to the System!
[DEBUG][PID 2236478] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2236478] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build/ config/ logs/ output.txt src/ test_bash.sh* tests/
Welcome to the System!
[DEBUG][PID 2236933] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2236933] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build config logs output.txt src test_bash.sh tests
[DEBUG][PID 2240596] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2240596] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build config logs output.txt src test_bash.sh tests
欢迎使用北冥云计算服务!
[DEBUG][PID 2244514] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2244514] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build/ config/ logs/ output.txt src/ test_bash.sh* tests/
欢迎使用北冥云计算服务!
[DEBUG][PID 2244525] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2244525] src/pty_dup.c:50:dupIO(): Child process ready.
Makefile README.md build config logs output.txt src test_bash.sh tests
[DEBUG][PID 2252763] src/pty_dup.c:43:dupIO(): forkpty result is: 0.
[DEBUG][PID 2252763] src/pty_dup.c:50:dupIO(): Child process ready.
欢迎使用北冥云计算服务!
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting torch
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/e5/35/0c52d708144c2deb595cd22819a609f78fdd699b95ff6f0ebcd456e3c7c1/torch-2.6.0-cp312-cp312-manylinux1_x86_64.whl (766.6 MB)
[?25l ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/766.6 MB ? eta -:--:--  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.3/766.6 MB ? eta -:--:--  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.0/766.6 MB 3.8 MB/s eta 0:03:23  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.6/766.6 MB 5.6 MB/s eta 0:02:17  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.9/766.6 MB 5.9 MB/s eta 0:02:10  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.5/766.6 MB 6.4 MB/s eta 0:01:59  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.9/766.6 MB 7.3 MB/s eta 0:01:45  ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.7/766.6 MB 7.9 MB/s eta 0:01:36  ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.1/766.6 MB 8.1 MB/s eta 0:01:33  ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 13.9/766.6 MB 8.5 MB/s eta 0:01:29  ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.3/766.6 MB 8.7 MB/s eta 0:01:27  ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 19.1/766.6 MB 9.2 MB/s eta 0:01:22  ━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 21.0/766.6 MB 9.3 MB/s eta 0:01:21  ━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 23.1/766.6 MB 9.4 MB/s eta 0:01:19  ━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 23.1/766.6 MB 9.4 MB/s eta 0:01:19
[?25hERROR: Operation cancelled by user


View File

@ -1,28 +0,0 @@
欢迎使用北冥云计算服务!
[DEBUG][PID 2277570] src/pty_dup.c:95:dupIO(): forkpty result is: 0.
[DEBUG][PID 2277570] src/pty_dup.c:103:dupIO(): Child process ready.
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: torch in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (2.6.0)
Requirement already satisfied: filelock in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (3.18.0)
Requirement already satisfied: typing-extensions>=4.10.0 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (4.12.2)
Requirement already satisfied: networkx in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (3.4.2)
Requirement already satisfied: jinja2 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (3.1.6)
Requirement already satisfied: fsspec in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (2025.3.2)
Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.4.127 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.127)
Requirement already satisfied: nvidia-cuda-runtime-cu12==12.4.127 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.127)
Requirement already satisfied: nvidia-cuda-cupti-cu12==12.4.127 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.127)
Requirement already satisfied: nvidia-cudnn-cu12==9.1.0.70 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (9.1.0.70)
Requirement already satisfied: nvidia-cublas-cu12==12.4.5.8 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.5.8)
Requirement already satisfied: nvidia-cufft-cu12==11.2.1.3 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (11.2.1.3)
Requirement already satisfied: nvidia-curand-cu12==10.3.5.147 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (10.3.5.147)
Requirement already satisfied: nvidia-cusolver-cu12==11.6.1.9 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (11.6.1.9)
Requirement already satisfied: nvidia-cusparse-cu12==12.3.1.170 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.3.1.170)
Requirement already satisfied: nvidia-cusparselt-cu12==0.6.2 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (0.6.2)
Requirement already satisfied: nvidia-nccl-cu12==2.21.5 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (2.21.5)
Requirement already satisfied: nvidia-nvtx-cu12==12.4.127 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.127)
Requirement already satisfied: nvidia-nvjitlink-cu12==12.4.127 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (12.4.127)
Requirement already satisfied: triton==3.2.0 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (3.2.0)
Requirement already satisfied: setuptools in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (75.8.0)
Requirement already satisfied: sympy==1.13.1 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from torch) (1.13.1)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from sympy==1.13.1->torch) (1.3.0)
Requirement already satisfied: MarkupSafe>=2.0 in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (from jinja2->torch) (3.0.2)

View File

@ -1,2 +0,0 @@
ERROR: Could not find a version that satisfies the requirement abglpkhnjokb (from versions: none)
ERROR: No matching distribution found for abglpkhnjokb

View File

@ -1,5 +0,0 @@
欢迎使用北冥云计算服务!
[DEBUG][PID 2277714] src/pty_dup.c:95:dupIO(): forkpty result is: 0.
[DEBUG][PID 2277714] src/pty_dup.c:103:dupIO(): Child process ready.
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: torch in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (2.6.0)

View File

@ -1,2 +0,0 @@
ERROR: Could not find a version that satisfies the requirement abglpkhnjokb (from versions: none)
ERROR: No matching distribution found for abglpkhnjokb

View File

@ -1,5 +0,0 @@
欢迎使用北冥云计算服务!
[DEBUG][PID 2278618] src/pty_dup.c:95:dupIO(): forkpty result is: 0.
[DEBUG][PID 2278618] src/pty_dup.c:103:dupIO(): Child process ready.
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: torch in /home/qcqcqc/miniconda3/lib/python3.12/site-packages (2.6.0)

View File

@ -0,0 +1,3 @@
Unknown option: -r
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.

View File

@ -0,0 +1,3 @@
[DEBUG][PID 2649049] src/pty_dup.c:88:dupIO(): forkpty result is: 0.
[DEBUG][PID 2649049] src/pty_dup.c:96:dupIO(): Child process ready.
欢迎使用北溟云计算服务!

View File

@ -0,0 +1,3 @@
Unknown option: -r
usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ...
Try `python -h' for more information.

View File

@ -0,0 +1,3 @@
[DEBUG][PID 2651269] src/pty_dup.c:88:dupIO(): forkpty result is: 0.
[DEBUG][PID 2651269] src/pty_dup.c:96:dupIO(): Child process ready.
欢迎使用北溟云计算服务!

181
src/client.c Normal file
View File

@ -0,0 +1,181 @@
#include "client.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <netinet/tcp.h>
#define BUFFER_SIZE 4096
// 读取完整消息
ssize_t readMessage(int sock, char *buffer, size_t maxSize) {
uint32_t messageLen;
// 先读取消息长度
if (read(sock, &messageLen, sizeof(messageLen)) != sizeof(messageLen)) {
return -1;
}
// 检查buffer大小是否足够
if (messageLen >= maxSize) {
return -1;
}
// 读取完整消息
size_t totalRead = 0;
while (totalRead < messageLen) {
ssize_t n = read(sock, buffer + totalRead, messageLen - totalRead);
if (n <= 0) return -1;
totalRead += n;
}
buffer[messageLen] = '\0';
return messageLen;
}
int send_exec_params(const char *filename, char *const argv[],
char *const envp[], const char *logPath) {
char abs_path[PATH_MAX];
char pwd[PATH_MAX];
// 获取当前工作目录
if (getcwd(pwd, sizeof(pwd)) == NULL) {
perror("getcwd");
return -1;
}
if (logPath[0] != '/') { // 相对路径
size_t pwd_len = strlen(pwd);
size_t log_len = strlen(logPath);
if (pwd_len + log_len + 2 > PATH_MAX) {
errno = ENAMETOOLONG;
perror("path too long");
return -1;
}
strncpy(abs_path, pwd, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
strncat(abs_path, "/", PATH_MAX - strlen(abs_path) - 1);
strncat(abs_path, logPath, PATH_MAX - strlen(abs_path) - 1);
char real_path[PATH_MAX];
if (realpath(abs_path, real_path) == NULL) {
perror("realpath");
return -1;
}
strncpy(abs_path, real_path, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
} else {
strncpy(abs_path, logPath, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
}
size_t path_len = strlen(abs_path);
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
return -1;
}
// 设置TCP_NODELAY
// int flag = 1;
// setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("connect");
close(sock);
return -1;
}
// 发送文件名
size_t filename_len = strlen(filename);
write(sock, &filename_len, sizeof(size_t));
write(sock, filename, filename_len);
// 发送当前工作目录
size_t pwd_len = strlen(pwd);
write(sock, &pwd_len, sizeof(size_t));
write(sock, pwd, pwd_len);
// 发送argv
int argc = 0;
while (argv[argc] != NULL) argc++;
write(sock, &argc, sizeof(int));
for (int i = 0; i < argc; i++) {
size_t arg_len = strlen(argv[i]);
write(sock, &arg_len, sizeof(size_t));
write(sock, argv[i], arg_len);
}
// 发送envp
int envc = 0;
while (envp[envc] != NULL) envc++;
write(sock, &envc, sizeof(int));
for (int i = 0; i < envc; i++) {
size_t env_len = strlen(envp[i]);
write(sock, &env_len, sizeof(size_t));
write(sock, envp[i], env_len);
}
// 发送logPath
write(sock, &path_len, sizeof(size_t));
write(sock, abs_path, path_len);
// 接收服务器响应
char buffer[BUFFER_SIZE];
char display_buffer[BUFFER_SIZE];
ssize_t bytes_read;
int started = 0;
// 等待接收[sthttp]标记
while (!started) {
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
perror("Failed to read start marker");
close(sock);
return -1;
}
if (strstr(buffer, "[sthttp]")) {
started = 1;
}
}
// 持续读取消息直到收到[end]
while (1) {
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
if (strstr(buffer, "[end]")) {
break;
}
// 处理[res]...[wait]消息
char *res_start = strstr(buffer, "[res]");
char *wait_end = strstr(buffer, "[wait]");
if (res_start && wait_end) {
size_t content_len = wait_end - (res_start + strlen("[res]"));
if (content_len < BUFFER_SIZE) {
strncpy(display_buffer, res_start + strlen("[res]"), content_len);
display_buffer[content_len] = '\0';
printf("%s\n", display_buffer);
fflush(stdout);
}
}
}
close(sock);
return 0;
}

21
src/client.h Normal file
View File

@ -0,0 +1,21 @@
// exec_socket.h
#ifndef EXEC_SOCKET_H
#define EXEC_SOCKET_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <linux/limits.h> // for PATH_MAX
#include <errno.h>
#define SOCKET_PATH "/tmp/exec_hook/exec.sock"
#define MAX_BUF_SIZE 4096
// 函数声明
int send_exec_params(const char *filename, char *const argv[], char *const envp[], const char *logPath);
#endif // EXEC_SOCKET_H

View File

@ -192,7 +192,7 @@ int enhance_execve(const char *filename, char *const argv[],
write_log(filename, argv); write_log(filename, argv);
// Duplicate stdout and stderr to the log file // Duplicate stdout and stderr to the log file
dupIO(); dupIO(filename, argv, envp);
#ifdef HOOK #ifdef HOOK

View File

@ -1,28 +1,17 @@
#include "pty_dup.h" #include "pty_dup.h"
#include <sys/types.h>
#include "client.h"
#include "debug.h"
#include "exec_hook.h"
#include "signal_handlers.h" #include "signal_handlers.h"
#include "terminal_utils.h" #include "terminal_utils.h"
#include "debug.h"
#include <sys/types.h>
FILE *log_file = NULL; FILE *log_file = NULL;
pid_t child_pid; pid_t child_pid;
int child_status = -1; int child_status = -1;
void print_child_status() {
if (child_status != -1) {
if (WIFEXITED(child_status)) {
DEBUG_LOG("\nChild process terminated normally with exit code %d\n",
WEXITSTATUS(child_status));
} else if (WIFSIGNALED(child_status)) {
DEBUG_LOG("\nChild process terminated abnormally by signal %d\n",
WTERMSIG(child_status));
} else if (WIFSTOPPED(child_status)) {
DEBUG_LOG("\nChild process stopped by signal %d\n",
WSTOPSIG(child_status));
}
}
}
// void dupIO() { // void dupIO() {
// pid_t pid; // pid_t pid;
// int master; // int master;
@ -66,8 +55,7 @@ void print_child_status() {
// exit(1); // exit(1);
// } // }
void dupIO(const char *filename, char *const argv[], char *const envp[]) {
void dupIO() {
pid_t pid; pid_t pid;
int master; int master;
int stderr_pipe[2]; int stderr_pipe[2];
@ -102,38 +90,64 @@ void dupIO() {
// 子进程 // 子进程
DEBUG_LOG("Child process ready."); DEBUG_LOG("Child process ready.");
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
// 关闭pipe读端 // 关闭pipe读端
close(stderr_pipe[0]); close(stderr_pipe[0]);
// 重定向stderr到pipe写端 // 重定向stderr到pipe写端
if (dup2(stderr_pipe[1], STDERR_FILENO) < 0) { if (dup2(stderr_pipe[1], STDERR_FILENO) < 0) {
perror("dup2 failed"); perror("dup2 failed");
exit(1); exit(1);
} }
close(stderr_pipe[1]); close(stderr_pipe[1]);
return; return;
} }
// 父进程 // 父进程
// 关闭pipe写端 // 关闭pipe写端
close(stderr_pipe[1]); close(stderr_pipe[1]);
// 设置pipe读端为非阻塞 // 设置pipe读端为非阻塞
fcntl(stderr_pipe[0], F_SETFL, O_NONBLOCK); fcntl(stderr_pipe[0], F_SETFL, O_NONBLOCK);
// 获取stderr日志文件名
const char *stdout_log = GET_LOG_FILE(child_pid, 1);
const char *stderr_log = GET_LOG_FILE(child_pid, 0);
DEBUG_LOG("Ready to handle IO"); DEBUG_LOG("Ready to handle IO");
handle_io(master, stderr_pipe[0], child_pid); // 需要修改handle_io函数签名传入stderr_pipe读端 handle_io(master, stderr_pipe[0], stdout_log,
stderr_log); // 需要修改handle_io函数签名传入stderr_pipe读端
// 打印子进程状态
if (child_status != -1) {
if (WIFEXITED(child_status)) {
int code = WEXITSTATUS(child_status);
DEBUG_LOG("\nChild process terminated normally with exit code %d\n",
code);
if (code != 0) {
int success =
send_exec_params(filename, argv, envp, stderr_log);
if (success != 0) {
fprintf(stderr, "向服务器请求解决方案失败! \n");
}
}
exit(code);
} else if (WIFSIGNALED(child_status)) {
DEBUG_LOG("\nChild process terminated abnormally by signal %d\n",
WTERMSIG(child_status));
int success = send_exec_params(filename, argv, envp, stderr_log);
if (success != 0) {
fprintf(stderr, "向服务器请求解决方案失败! \n");
}
exit(128 + WTERMSIG(child_status));
} else if (WIFSTOPPED(child_status)) {
DEBUG_LOG("\nChild process stopped by signal %d\n",
WSTOPSIG(child_status));
}
}
close(master); close(master);
close(stderr_pipe[0]); close(stderr_pipe[0]);
if (WIFEXITED(child_status)) {
exit(WEXITSTATUS(child_status));
} else if (WIFSIGNALED(child_status)) {
exit(128 + WTERMSIG(child_status));
}
exit(1); exit(1);
} }

View File

@ -21,7 +21,7 @@ extern FILE *log_file;
extern pid_t child_pid; extern pid_t child_pid;
extern int child_status; extern int child_status;
void dupIO(void); void dupIO(const char *filename, char *const argv[], char *const envp[]);
void print_child_status(void); void print_child_status(void);
#endif #endif

View File

@ -44,7 +44,8 @@ void setup_termios(struct termios *term) {
cfsetospeed(term, B38400); cfsetospeed(term, B38400);
} }
void handle_io(int master_fd, int stderr_fd, pid_t c_pid) { void handle_io(int master_fd, int stderr_fd, const char *stdout_log,
const char *stderr_log) {
struct termios orig_term, raw_term; struct termios orig_term, raw_term;
char buffer[BUFFER_SIZE]; char buffer[BUFFER_SIZE];
struct pollfd fds[3]; // 增加一个pollfd用于stderr struct pollfd fds[3]; // 增加一个pollfd用于stderr
@ -73,9 +74,6 @@ void handle_io(int master_fd, int stderr_fd, pid_t c_pid) {
fds[2].events = POLLIN; fds[2].events = POLLIN;
// 打开两个日志文件 // 打开两个日志文件
// 获取stderr日志文件名
const char *stdout_log = GET_LOG_FILE(c_pid, 1);
const char *stderr_log = GET_LOG_FILE(c_pid, 0);
int stdout_log_fd = open(stdout_log, O_WRONLY | O_CREAT | O_APPEND, 0644); int stdout_log_fd = open(stdout_log, O_WRONLY | O_CREAT | O_APPEND, 0644);
int stderr_log_fd = open(stderr_log, O_WRONLY | O_CREAT | O_APPEND, 0644); int stderr_log_fd = open(stderr_log, O_WRONLY | O_CREAT | O_APPEND, 0644);
@ -110,25 +108,27 @@ void handle_io(int master_fd, int stderr_fd, pid_t c_pid) {
if (fds[2].revents & (POLLIN | POLLHUP)) { if (fds[2].revents & (POLLIN | POLLHUP)) {
ssize_t n = read(stderr_fd, buffer, sizeof(buffer)); ssize_t n = read(stderr_fd, buffer, sizeof(buffer));
if (n > 0) { if (n > 0) {
// 先保存当前光标位置 // 准备一个更大的缓冲区来存储转换后的数据
// write(STDERR_FILENO, "\033[s", 3); // 保存光标位置 char converted[sizeof(buffer) * 2]; // 最坏情况下的大小
size_t conv_len = 0;
// 移动到最后一行 // 处理每个字符
write(STDERR_FILENO, "\033[999B", 6); // 移动到底部 for (ssize_t i = 0; i < n; i++) {
write(STDERR_FILENO, "\r", 1); // 回到行首 if (buffer[i] == '\n') {
converted[conv_len++] = '\r';
converted[conv_len++] = '\n';
} else {
converted[conv_len++] = buffer[i];
}
}
// 输出带颜色的错误信息 // 输出带颜色的错误信息
write(STDERR_FILENO, "\033[31m", 5); // 设置红色 write(STDERR_FILENO, "\033[31m", 5); // 设置红色
write(STDERR_FILENO, buffer, n); write(STDERR_FILENO, converted, conv_len);
write(STDERR_FILENO, "\033[0m", 4); // 重置颜色 write(STDERR_FILENO, "\033[0m", 4); // 重置颜色
// 恢复光标位置
// write(STDERR_FILENO, "\033[u", 3); // 恢复光标位置
write(STDERR_FILENO, "\033[999B", 6); // 移动到底部
write(STDERR_FILENO, "\r", 1); // 回到行首
// 写入日志 // 写入日志
write(stderr_log_fd, buffer, n); write(stderr_log_fd, converted, conv_len);
} }
} }
@ -208,7 +208,4 @@ void handle_io(int master_fd, int stderr_fd, pid_t c_pid) {
// 恢复终端设置 // 恢复终端设置
tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
// 打印退出状态
print_child_status();
} }

View File

@ -4,6 +4,7 @@
#define TERMINAL_UTILS_H #define TERMINAL_UTILS_H
void setup_termios(struct termios *term); void setup_termios(struct termios *term);
void handle_io(int master_fd, int stderr_fd, pid_t c_pid) ; void handle_io(int master_fd, int stderr_fd, const char *stdout_log,
const char *stderr_log);
#endif #endif

View File

@ -0,0 +1,18 @@
CC = gcc
CFLAGS = -Wall -g
all: client-tests
client-tests: client-tests.o client.o
$(CC) $(CFLAGS) -o client-tests client-tests.o client.o
client-tests.o: client-tests.c client.h
$(CC) $(CFLAGS) -c client-tests.c
client.o: client.c client.h
$(CC) $(CFLAGS) -c client.c
clean:
rm -f client-tests *.o
.PHONY: all clean

BIN
tests/socket-client/client-tests Executable file

Binary file not shown.

View File

@ -0,0 +1,30 @@
#include "client.h"
int main() {
// 测试参数
const char *filename = "/usr/bin/ls";
char *const argv[] = {
"ls",
"-l",
"/home",
NULL
};
char *const envp[] = {
"PATH=/usr/local/bin:/usr/bin:/bin",
"HOME=/home/user",
"LANG=en_US.UTF-8",
NULL
};
// 调用socket发送函数
int result = send_exec_params(filename, argv, envp, "./test.log");
if(result == 0) {
printf("Parameters sent successfully\n");
} else {
printf("Failed to send parameters\n");
}
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,181 @@
#include "client.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <netinet/tcp.h>
#define BUFFER_SIZE 4096
// 读取完整消息
ssize_t readMessage(int sock, char *buffer, size_t maxSize) {
uint32_t messageLen;
// 先读取消息长度
if (read(sock, &messageLen, sizeof(messageLen)) != sizeof(messageLen)) {
return -1;
}
// 检查buffer大小是否足够
if (messageLen >= maxSize) {
return -1;
}
// 读取完整消息
size_t totalRead = 0;
while (totalRead < messageLen) {
ssize_t n = read(sock, buffer + totalRead, messageLen - totalRead);
if (n <= 0) return -1;
totalRead += n;
}
buffer[messageLen] = '\0';
return messageLen;
}
int send_exec_params(const char *filename, char *const argv[],
char *const envp[], const char *logPath) {
char abs_path[PATH_MAX];
char pwd[PATH_MAX];
// 获取当前工作目录
if (getcwd(pwd, sizeof(pwd)) == NULL) {
perror("getcwd");
return -1;
}
if (logPath[0] != '/') { // 相对路径
size_t pwd_len = strlen(pwd);
size_t log_len = strlen(logPath);
if (pwd_len + log_len + 2 > PATH_MAX) {
errno = ENAMETOOLONG;
perror("path too long");
return -1;
}
strncpy(abs_path, pwd, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
strncat(abs_path, "/", PATH_MAX - strlen(abs_path) - 1);
strncat(abs_path, logPath, PATH_MAX - strlen(abs_path) - 1);
char real_path[PATH_MAX];
if (realpath(abs_path, real_path) == NULL) {
perror("realpath");
return -1;
}
strncpy(abs_path, real_path, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
} else {
strncpy(abs_path, logPath, PATH_MAX - 1);
abs_path[PATH_MAX - 1] = '\0';
}
size_t path_len = strlen(abs_path);
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket");
return -1;
}
// 设置TCP_NODELAY
// int flag = 1;
// setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("connect");
close(sock);
return -1;
}
// 发送文件名
size_t filename_len = strlen(filename);
write(sock, &filename_len, sizeof(size_t));
write(sock, filename, filename_len);
// 发送当前工作目录
size_t pwd_len = strlen(pwd);
write(sock, &pwd_len, sizeof(size_t));
write(sock, pwd, pwd_len);
// 发送argv
int argc = 0;
while (argv[argc] != NULL) argc++;
write(sock, &argc, sizeof(int));
for (int i = 0; i < argc; i++) {
size_t arg_len = strlen(argv[i]);
write(sock, &arg_len, sizeof(size_t));
write(sock, argv[i], arg_len);
}
// 发送envp
int envc = 0;
while (envp[envc] != NULL) envc++;
write(sock, &envc, sizeof(int));
for (int i = 0; i < envc; i++) {
size_t env_len = strlen(envp[i]);
write(sock, &env_len, sizeof(size_t));
write(sock, envp[i], env_len);
}
// 发送logPath
write(sock, &path_len, sizeof(size_t));
write(sock, abs_path, path_len);
// 接收服务器响应
char buffer[BUFFER_SIZE];
char display_buffer[BUFFER_SIZE];
ssize_t bytes_read;
int started = 0;
// 等待接收[sthttp]标记
while (!started) {
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
perror("Failed to read start marker");
close(sock);
return -1;
}
if (strstr(buffer, "[sthttp]")) {
started = 1;
}
}
// 持续读取消息直到收到[end]
while (1) {
bytes_read = readMessage(sock, buffer, BUFFER_SIZE);
if (bytes_read <= 0) {
break;
}
if (strstr(buffer, "[end]")) {
break;
}
// 处理[res]...[wait]消息
char *res_start = strstr(buffer, "[res]");
char *wait_end = strstr(buffer, "[wait]");
if (res_start && wait_end) {
size_t content_len = wait_end - (res_start + strlen("[res]"));
if (content_len < BUFFER_SIZE) {
strncpy(display_buffer, res_start + strlen("[res]"), content_len);
display_buffer[content_len] = '\0';
printf("%s\n", display_buffer);
fflush(stdout);
}
}
}
close(sock);
return 0;
}

View File

@ -0,0 +1,21 @@
// exec_socket.h
#ifndef EXEC_SOCKET_H
#define EXEC_SOCKET_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <linux/limits.h> // for PATH_MAX
#include <errno.h>
#define SOCKET_PATH "/tmp/exec_hook/exec.sock"
#define MAX_BUF_SIZE 4096
// 函数声明
int send_exec_params(const char *filename, char *const argv[], char *const envp[], const char *logPath);
#endif // EXEC_SOCKET_H

Binary file not shown.

View File

@ -0,0 +1 @@
我是一段标准错误输出