#include "precompile.h" #include "osutil.h" #include "memutil.h" #include "strutil.h" #include "toolkit.h" //#define NEW_FEATURE #ifdef _WIN32 #include TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr) { HANDLE hSnapshot; int rc = TRUE; DWORD dwCurProcID = GetCurrentProcessId(); int count = 0; if (alive) *alive = 0; hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot) { PROCESSENTRY32 pe; pe.dwSize = sizeof(pe); if (Process32First(hSnapshot, &pe)) { do { int i; for (i = 0; i < nNum; i++) { if (stricmp(&pe.szExeFile[0], pNames[i]) == 0 && pe.th32ProcessID != dwCurProcID) { rc = FALSE; count++; break; } } } while (Process32Next(hSnapshot, &pe)); } CloseHandle(hSnapshot); } if (alive) *alive = count; return rc; } TOOLKIT_API int osutil_restart_system() { HANDLE hToken; TOKEN_PRIVILEGES tkp; BOOL fResult; // Get the current process token handle so we can get shutdown privilege. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { fprintf(stderr, "get proc token fail"); return -1; } // Get the LUID for shutdown privilege. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; // one privilege to set tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // Get shutdown privilege for this process. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); // Cannot test the return value of AdjustTokenPrivileges. if (GetLastError() != ERROR_SUCCESS) { fprintf(stderr, "adjust proc token privilege fail"); return -1; } // Display the shutdown dialog box and start the countdown. fResult = InitiateSystemShutdown( NULL, // shut down local computer NULL, // message for user 0, // time-out period, in seconds FALSE, // ask user to close apps TRUE); // reboot after shutdown if (!fResult) { fprintf(stderr, "request windows reboot fail"); return -1; } // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); return 0; } TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size) { const DWORD dwCurProcessID = GetCurrentProcessId(); DWORD relateProcessIDs[256]; DWORD dwIdx = 0; char szCmd[256]; DWORD relateProcessNum = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); memset(relateProcessIDs, 0, sizeof(relateProcessIDs)); if (hSnapshot) { PROCESSENTRY32 pe; pe.dwSize = sizeof(pe); if (Process32First(hSnapshot, &pe)) { do { int i; for (i = 0; i < array_size; i++) { if (stricmp(&pe.szExeFile[0], process_array[i]) == 0 && pe.th32ProcessID != dwCurProcessID) { relateProcessIDs[relateProcessNum++] = pe.th32ProcessID; break; } } } while (Process32Next(hSnapshot, &pe)); } CloseHandle(hSnapshot); } for (dwIdx = 0; dwIdx < relateProcessNum; ++dwIdx) { sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", relateProcessIDs[dwIdx]); WinExec(szCmd, SW_HIDE); } } TOOLKIT_API int osutil_uname(tk_utsname_t* buffer) { return TOOLKIT_UNKNOWN; } #else #include #include #include // for opendir(), readdir(), closedir() #include // for stat() #include #include #include #include #include #define DEFAULT_PROCESS_CMDLINE_SIZE 56 #define DEFAULT_PROCESS_PATH_SIZE 8192 #define DEFAULT_PROCESS_NAME_SIZE 1024 static inline int is_num(const char* chars) { for (; *chars; chars++) if (*chars < '0' || *chars > '9') return 0; // false return 1; // true } static int execute_cmd_return_result(const char* cmd, char* result) { char buf_ps[1024]; char ps[1024] = { 0 }; FILE* ptr; strcpy(ps, cmd); if ((ptr = popen(ps, "r")) != NULL) { while (fgets(buf_ps, 1024, ptr) != NULL) { strcat(result, buf_ps); if (strlen(result) > 1024) break; } int len = strlen(result); int i; for (i = len - 1; i >= 0 && result[i] == '\n'; --i) { result[i] = '\0'; } pclose(ptr); return 0; } else { printf("popen %s error\n", ps); return -1; } } static int private_get_running_process_ids(int* alive, alive_process_info* alive_process_arr, const char* process_name) { int ret = 0, capacity, count, idx; char content[1025]; char cmd[256]; const int cur_pid = (int)getpid(); memset(content, 0, sizeof(content)); capacity = *alive; *alive = 0; idx = count = 0; sprintf(cmd, "pgrep -u root -d '|' %s", process_name); ret = execute_cmd_return_result(cmd, content); if (ret == 0 && strlen(content) > 0) { char** elems = strsplit(content, "|"); if (elems != NULL) { char** p; for (p = elems; *p != NULL; ++p) { int pid; pid = atoi(*p); if(pid == cur_pid) continue; printf("%d: %s, %d\n", count, *p, pid); if (count < capacity) { alive_process_arr[count].pid = pid; strcpy(alive_process_arr[count].name, process_name); strcpy(alive_process_arr[count].path, process_name); idx++; } count++; } strfreev(elems); } } *alive = idx; return count; } #ifdef NEW_FEATURE TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr) { int i = 0; int count = 0, capacity = 0; int real = 0; if (alive) { if (alive_process_arr) capacity = *alive; *alive = 0; } for (i = 0; i < nNum; ++i) { int cap = capacity - count; int result = private_get_running_process_ids(&cap, alive_process_arr + count, pNames[i]); count += cap; real += result; } if (alive) { *alive = real; } return (real > 0) ? FALSE : TRUE; } #else TOOLKIT_API int osutil_detect_unique_app(char** pNames, int nNum, int* alive, alive_process_info* alive_process_arr) { int rc = TRUE; DIR* dir_proc = NULL; struct dirent* dir_entity = NULL; int i = 0; int count = 0, capacity = 0; char cmdLinePath[DEFAULT_PROCESS_CMDLINE_SIZE] = { 0 }; char processName[DEFAULT_PROCESS_NAME_SIZE] = { 0 }; char processPath[DEFAULT_PROCESS_PATH_SIZE] = { 0 }; pid_t pid = (pid_t)-1; const pid_t cur_pid = getpid(); if (alive) { if (alive_process_arr) capacity = *alive; *alive = 0; } dir_proc = opendir("/proc/"); if (dir_proc == NULL) { return FALSE; } while ((dir_entity = readdir(dir_proc))) { if (dir_entity->d_type == DT_DIR) { if (is_num(dir_entity->d_name)) { pid = (pid_t)atoi(dir_entity->d_name); if (pid == getpid()) { continue; } strcpy(cmdLinePath, "/proc/"); strcat(cmdLinePath, dir_entity->d_name); strcat(cmdLinePath, "/cmdline"); //printf("%s: open(%s)...\n", __FUNCTION__, cmdLinePath); FILE* fd_cmdline = fopen(cmdLinePath, "rt"); if (fd_cmdline != NULL) { memset(processName, 0, DEFAULT_PROCESS_NAME_SIZE); memset(processPath, 0, DEFAULT_PROCESS_PATH_SIZE); ///**TODO(Gifur@1/10/2022): 读文件的所有内容并通过结束符0x00去拆分 */ fscanf(fd_cmdline, "%s", processPath); //printf("%s: close(%p)...\n", __FUNCTION__, fd_cmdline); fclose(fd_cmdline); //printf("%s: close(%p) done!\n", __FUNCTION__, fd_cmdline); if (strrchr(processPath, '/')) { strcpy(processName, strrchr(processPath, '/') + 1); } else { strcpy(processName, processPath); } for (i = 0; i < nNum; i++) { if (strcasecmp(processName, pNames[i]) == 0) { printf("%s, %s, %d, %d\n", processPath, processName, pid, cur_pid); if (count < capacity) { if (strlen(processPath) > ALIVE_PROCESS_PATH_LEN - 1) { processPath[ALIVE_PROCESS_PATH_LEN - 1] = '\0'; processPath[ALIVE_PROCESS_PATH_LEN - 2] = '.'; processPath[ALIVE_PROCESS_PATH_LEN - 3] = '.'; processPath[ALIVE_PROCESS_PATH_LEN - 4] = '.'; } strcpy(alive_process_arr[count].path, processPath); alive_process_arr[count].pid = pid; strcpy(alive_process_arr[count].name, processName); } count++; rc = FALSE; break; } } } else { printf("%s: open(%s) failed %d!!\n", __FUNCTION__, cmdLinePath, errno); } } } if (!rc && !alive) { break; } } printf("%s: closedir(%p)...\n", __FUNCTION__, dir_proc); closedir(dir_proc); printf("%s: closedir(%p) done!\n", __FUNCTION__, dir_proc); if (alive) *alive = count; printf("%s: exit!\n", __FUNCTION__); return rc; } #endif TOOLKIT_API int osutil_restart_system() { int result = -1; sync(); result = reboot(RB_AUTOBOOT); return result; } #ifdef NEW_FEATURE TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size) { int i, j, k; const pid_t cur_pid = getpid(); k = 0; for (i = 0; i < array_size; ++i) { int count = 50; alive_process_info processes[50]; memset(processes, 0, sizeof(processes)); int result = private_get_running_process_ids(&count, processes, process_array[i]); for (j = 0; j < count; ++j) { printf("kill %s, %s, %d, %d\n", processes[j].path, processes[j].name, processes[j].pid, cur_pid); int r = kill(processes[j].pid, SIGKILL); if (r != 0) { printf("kill of pid=%d failed:%d\n", processes[j].pid, errno); } else { k++; } } } printf("total kill process count: %d\n", k); } #else TOOLKIT_API void osutil_terminate_related_process(char** process_array, const int array_size) { DIR* dir_proc = NULL; struct dirent* dir_entity = NULL; int i = 0; int count = 0; char cmdLinePath[DEFAULT_PROCESS_CMDLINE_SIZE] = { 0 }; char processName[DEFAULT_PROCESS_NAME_SIZE] = { 0 }; char processPath[DEFAULT_PROCESS_PATH_SIZE] = { 0 }; const pid_t cur_pid = getpid(); dir_proc = opendir("/proc/"); if (dir_proc == NULL) { goto finished; } while ((dir_entity = readdir(dir_proc))) { if (dir_entity->d_type == DT_DIR) { if (is_num(dir_entity->d_name)) { pid_t pid = (pid_t)atoi(dir_entity->d_name); if (pid == getpid()) { continue; } strcpy(cmdLinePath, "/proc/"); strcat(cmdLinePath, dir_entity->d_name); strcat(cmdLinePath, "/cmdline"); //printf("%s: open(%s)...\n", __FUNCTION__, cmdLinePath); FILE* fd_cmdline = fopen(cmdLinePath, "rt"); if (fd_cmdline != NULL) { memset(processName, 0, DEFAULT_PROCESS_NAME_SIZE); memset(processPath, 0, DEFAULT_PROCESS_PATH_SIZE); fscanf(fd_cmdline, "%s", processPath); //printf("%s: close(%p)...\n", __FUNCTION__, fd_cmdline); fclose(fd_cmdline); //printf("%s: close(%p) done!\n", __FUNCTION__, fd_cmdline); if (strrchr(processPath, '/')) { strcpy(processName, strrchr(processPath, '/') + 1); } else { strcpy(processName, processPath); } for (i = 0; i < array_size; i++) { if (strcasecmp(processName, process_array[i]) == 0) { printf("kill %s, %s, %d, %d\n", processPath, processName, pid, cur_pid); int r = kill(pid, SIGKILL); if (r != 0) { printf("kill of pid=%d failed:%d\n", pid, errno); } else { count++; } break; } } } else { printf("%s: open(%s) failed %d!!\n", __FUNCTION__, cmdLinePath, errno); } } } } closedir(dir_proc); finished: printf("total kill process count: %d\n", count); } #endif /*cat /ect/os-release*/ TOOLKIT_API int osutil_uname(tk_utsname_t* buffer) { struct utsname buf; int r; if (buffer == NULL) return TOOLKIT_EINVAL; if (uname(&buf) == -1) { r = TOOLKIT__ERR(errno); goto error; } r = strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname)); if (r == TOOLKIT_E2BIG) goto error; r = strscpy(buffer->release, buf.release, sizeof(buffer->release)); if (r == TOOLKIT_E2BIG) goto error; r = strscpy(buffer->version, buf.version, sizeof(buffer->version)); if (r == TOOLKIT_E2BIG) goto error; r = strscpy(buffer->machine, buf.machine, sizeof(buffer->machine)); if (r == TOOLKIT_E2BIG) goto error; return 0; error: buffer->sysname[0] = '\0'; buffer->release[0] = '\0'; buffer->version[0] = '\0'; buffer->machine[0] = '\0'; return r; } #endif TOOLKIT_API int osutil_shutdown_system() { //system("poweroff"); system("shutdown -h now"); return 0; }