亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

Linux如何獲取進程的基地信息

2023-08-25 16:11:42 來源:大川搬磚

1. 問題

執(zhí)行程序時,與程序同目錄下存在一 config/ 目錄,其中存放了 json 格式的配置文件。進行部署時需要將程序和 config/ 目錄放在同一位置。那么,問題來了,如何保證不管這個程序部署到什么位置,不管以什么方式運行,程序自己都能訪問到配置文件呢?

解決問題之前,先說一下進程的工作目錄——Current Working Directory。


(資料圖片僅供參考)

2. 什么是進程的工作目錄

進程的工作目錄是指進程的調(diào)用者在啟動進程對應(yīng)的程序時, 調(diào)用者所在的目錄。比如說,在 /home/sdc/ 目錄下有一個可執(zhí)行程序 hello-world。如果在根目錄下啟動 hello-world,那么 hello-world 進程的工作目錄為根目錄 / 。如果在 /home/sdc 目錄下啟動 hello-world,那么其工作目錄為 /home/sdc。

LinuxC 中,有兩個函數(shù)可以獲取進程工作目錄:getcwd() 和 readlink()。

2.1 getcwd()

man 3 getcwd():https://man7.org/linux/man-pages/man2/getcwd.2.html

#include < unistd.h >char *getcwd(char *buf, size_t size);

該函數(shù)將獲取到的進程工作目錄的絕對路徑存儲在形參 buf 中。同時也會返回一個指針,指針指向的內(nèi)容和 buf 存儲的內(nèi)容相同。如果路徑的長度比 size 大,那么該函數(shù)返回為 NULL。

2.2 readlink()

man 2 readlink:https://www.man7.org/linux/man-pages/man2/readlink.2.html

#include < unistd.h >ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

該函數(shù)用于獲取符號鏈接所指的文件。借助 /proc/self/cwd,即 pathname = "/proc/self/cwd",readlink() 即可獲得當前進程的工作目錄。

該函數(shù)同樣將進程工作目錄的絕對路徑存儲在形參 buf 中,并返回存儲的路徑長度。但是,buf 中存儲路徑不帶字符串結(jié)束符 "?"。而且,如果返回的長度和 bufsiz 相同,那么路徑信息很可能被截取了。

2.3 簡單例程

hello-world.c:

#include < stdio.h >#include < stdlib.h >#include < string.h >#include < unistd.h >int main(int argc, char *argv[]){    char work_dir[64] = {0};    int dir_size = 0;    getcwd(work_dir, sizeof(work_dir)))    printf("getcwd:%sn", work_dir);    memset(work_dir, 0, sizeof(work_dir));    dir_size = readlink("/proc/self/cwd", work_dir, sizeof(work_dir));    work_dir[dir_size] = "?";    printf("readlink:%sn", work_dir);    return 0;}

執(zhí)行結(jié)果:

3. 獲取進程對應(yīng)程序的絕對路徑

如果想要解決文章開頭提出的問題,那么進程需要獲取程序所在的絕對路徑。該功能通過 readlink(const char *pathname, char *buf, size_t bufsiz)實現(xiàn)。不過 pathname 不再是 /proc/self/cwd,而是 /proc/self/exe

開箱即用代碼

#include < stdio.h >#include < stdlib.h >#include < string.h >#include < unistd.h >#include < stdint.h >#include < fcntl.h >#define CONFIG_FILENAME    "./config/psl.json"http://get current process elf absolutepathstaticint32_t curr_elf_abs_path_get(int8_t *path_buf, int32_t buf_size){    ssize_t len = 0;    int32_t i = 0;    len = readlink("/proc/self/exe", path_buf, buf_size);    if(-1 == len)    {        perror("readlinkn");        return -1;    }    if(len == buf_size)    {        printf("Warn:path may be truncatedn");    }    //from last to head, find first "/"    for(i = len; i > 0; i--)    {        if(path_buf[i] == "/")        {            path_buf[i + 1] = "?";            break;        }    }    return 0;}int main(int argc, char *argv[]){    int8_t elf_path[128] = {0};    int8_t config_file_path[256] = {0};    int fd = -1;    int32_t i = 0;    int32_t ret = 0;    ret = curr_elf_abs_path_get(elf_path, sizeof(elf_path));    if(0 != ret)    {        printf("get exe path failedn");        return -1;    }    printf("current process exe absolute path:%sn", elf_path);    sprintf(config_file_path, "%s%s", elf_path, CONFIG_FILENAME);    fd = open(config_file_path, O_RDWR);    if(-1 == fd)    {        perror("open");        return -1;    }    printf("open %s successn", config_file_path);    close(fd);    return 0;}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)project(exe-abs-path C)set(CMAKE_VERBOSE_MAKEFILE ON)add_executable(${PROJECT_NAME} main.c)

執(zhí)行結(jié)果:

4. 總結(jié)

我當然可以借助 shell 腳本解決該問題??墒?,我還是喜歡讓程序自己”實現(xiàn)“該功能,這樣我在部署和使用時會方便很多。

5. 說明

/proc/self/目錄中存放了當前進程的很多有用信息。

/proc/self/fd/:進程打開的文件描述符;

/proc/self/cmdline:進程被執(zhí)行時,命令行中輸入的命令;

/proc/self/task:進程中包含的線程 id;

/proc/self/environ:進程運行時的環(huán)境變量信息。

標簽:

上一篇:適用于筆記本電腦的車載DC-DC轉(zhuǎn)換器電路圖
下一篇:最后一頁