#include "client.h" #include #include #include #include #include #include #include #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; }