Browse Source

兼容Linux

xx 2 years ago
parent
commit
f44caeedb7
4 changed files with 90 additions and 7 deletions
  1. 1 1
      include/util/process.h
  2. 1 1
      src/net/http_website.cpp
  3. 2 2
      src/util/file.cpp
  4. 86 3
      src/util/process.cpp

+ 1 - 1
include/util/process.h

@@ -8,7 +8,6 @@ namespace ylib
 {
 	namespace process
 	{
-#ifdef _WIN32
 		// 取进程路径
 		std::string getpath(uint32 process_id);
 		/*进程信息*/
@@ -33,6 +32,7 @@ namespace ylib
 		std::list<ylib::process::proc_info> list();
 		// 是否存在
 		size_t exist(const std::string& filepath);
+#ifdef _WIN32
 		// 检测多开
 		bool already_running(const std::string& name);
 		// 设置为启动

+ 1 - 1
src/net/http_website.cpp

@@ -98,7 +98,7 @@ bool ylib::network::http::website::start(const website_config& config)
     }
     if (m_session_local_storage->open(m_config.session.dirpath) == false)
     {
-        m_lastErrorDesc = "session open failed, dirpath: " + m_config.session.dirpath;
+        m_lastErrorDesc = "session open failed("+m_session_local_storage->last_error() + "), dirpath: " + m_config.session.dirpath;
         return false;
     }
     if (m_router->start(m_config.router) == false)

+ 2 - 2
src/util/file.cpp

@@ -389,11 +389,11 @@ void ylib::file::copy_dir(const std::string& src, const std::string& dst)
     auto map = traverse(src,".*");
     for_iter(iter, map) {
         if (iter->second == IS_DIRECTORY)
-            ylib::file::create_dir(dst+"\\"+iter->first,true);
+            ylib::file::create_dir(dst+"/"+iter->first,true);
     }
     for_iter(iter, map) {
         if (iter->second == IS_FILE)
-            ylib::file::copy(src+"\\" + iter->first, dst + "\\" + iter->first);
+            ylib::file::copy(src+"/" + iter->first, dst + "/" + iter->first);
     }
 }
 std::map<std::string, ylib::FileType> ylib::file::traverse(const std::string& dirpath, const std::string& regex_pattern)

+ 86 - 3
src/util/process.cpp

@@ -5,13 +5,19 @@
 #include <psapi.h>
 #include <tlhelp32.h>
 #else
+#include <iterator>
 #include <unistd.h>
 #include <limits.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <cstdlib>
+#include <dirent.h>
+#include <fstream>
+#include <sstream>
 #endif
 #include <sstream>
 #include <sys/types.h>
 #include <signal.h>
-#ifdef _WIN32
 bool ylib::process::create(const std::string& filepath, const std::string& working_directory, const std::vector<std::string>& args, bool wait_close, bool show_window, size_t* pid)
 {
 #ifdef _WIN32
@@ -63,7 +69,51 @@ bool ylib::process::create(const std::string& filepath, const std::string& worki
 
     return true;
 #else
-    return false;
+    // 创建一个子进程
+    pid_t pid_fork = fork();
+    if (pid_fork == -1) {
+        // fork失败
+        return false;
+    }
+    else if (pid_fork == 0) {
+        // 在子进程中
+
+        // 如果不显示窗口,设置stdin、stdout和stderr为/dev/null
+        if (!show_window) {
+            int dev_null = open("/dev/null", O_RDWR);
+            dup2(dev_null, STDIN_FILENO);
+            dup2(dev_null, STDOUT_FILENO);
+            dup2(dev_null, STDERR_FILENO);
+            close(dev_null);
+        }
+
+        // 构建参数列表
+        std::vector<char*> argv;
+        argv.push_back(const_cast<char*>(filepath.c_str()));
+        for (const auto& arg : args) {
+            argv.push_back(const_cast<char*>(arg.c_str()));
+        }
+        argv.push_back(nullptr);  // 参数列表以nullptr结尾
+
+        // 执行新的程序
+        execvp(filepath.c_str(), argv.data());
+        // 如果execvp返回,说明发生了错误
+        exit(EXIT_FAILURE);
+    }
+    else {
+        // 在父进程中
+        if (pid != nullptr) {
+            *pid = static_cast<size_t>(pid_fork);
+        }
+
+        // 如果需要等待子进程结束
+        if (wait_close) {
+            int status;
+            waitpid(pid_fork, &status, 0);
+        }
+
+        return true;
+    }
 #endif
 }
 bool ylib::process::destory(uint32 process_id)
@@ -84,6 +134,7 @@ bool ylib::process::destory(uint32 process_id)
 std::list<ylib::process::proc_info> ylib::process::list()
 {
     std::list<ylib::process::proc_info> processList;
+#ifdef _WIN32
     HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if (hSnapshot == INVALID_HANDLE_VALUE) {
         return processList;
@@ -100,6 +151,37 @@ std::list<ylib::process::proc_info> ylib::process::list()
         } while (Process32Next(hSnapshot, &pe32));
     }
     CloseHandle(hSnapshot);
+#else
+    DIR* dir = opendir("/proc");
+    if (dir != nullptr) {
+        struct dirent* entry;
+        while ((entry = readdir(dir)) != nullptr) {
+            int pid = atoi(entry->d_name);
+            if (pid > 0) {  // 过滤掉非数字目录
+                proc_info info;
+                info.pid = pid;
+
+                // 读取进程名和父进程ID
+                std::string pid_path = "/proc/" + std::to_string(pid) + "/stat";
+                std::ifstream stat_file(pid_path);
+                if (stat_file.is_open()) {
+                    std::string line;
+                    std::getline(stat_file, line);
+                    std::istringstream iss(line);
+                    std::vector<std::string> tokens(std::istream_iterator<std::string>{iss},
+                        std::istream_iterator<std::string>());
+
+                    if (tokens.size() > 3) {
+                        info.name = tokens[1];  // 通常是进程名
+                        info.parent_pid = std::stoul(tokens[3]);  // 父进程ID
+                    }
+                    processList.push_back(info);
+                }
+            }
+        }
+        closedir(dir);
+    }
+#endif
     return processList;
 }
 // 取进程路径
@@ -141,6 +223,7 @@ size_t ylib::process::exist(const std::string& filepath)
     }
     return 0;
 }
+#ifdef _WIN32
 // 检测多开
 bool ylib::process::already_running(const std::string& name)
 {
@@ -165,4 +248,4 @@ bool ylib::process::running(const std::string& name)
     }
     return true;
 }
-#endif
+#endif