2011-04-02 112 views
16

使用readlink函數作爲How do I find the location of the executable in C?的解決方案,我將如何獲取char數組的路徑?另外,buf和bufsize所代表的變量是什麼,以及如何對它們進行初始化?如何實現readlink以查找路徑

編輯:我想獲得當前正在運行的程序的路徑,就像上面鏈接的問題。該問題的答案表示使用readlink("proc/self/exe")。我不知道如何將其實施到我的程序中。我試過了:

char buf[1024]; 
string var = readlink("/proc/self/exe", buf, bufsize); 

這顯然是不正確的。

回答

31

這個Use the readlink() function properlyreadlink功能的正確使用。

如果你有一個std::string你的路徑,你可以做這樣的事情:

#include <unistd.h> 
#include <limits.h> 

std::string do_readlink(std::string const& path) { 
    char buff[PATH_MAX]; 
    ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1); 
    if (len != -1) { 
     buff[len] = '\0'; 
     return std::string(buff); 
    } 
    /* handle error condition */ 
} 

如果你只是一個固定的路徑之後是:

std::string get_selfpath() { 
    char buff[PATH_MAX]; 
    ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1); 
    if (len != -1) { 
     buff[len] = '\0'; 
     return std::string(buff); 
    } 
    /* handle error condition */ 
} 

要使用它:

int main() 
{ 
    std::string selfpath = get_selfpath(); 
    std::cout << selfpath << std::endl; 
    return 0; 
} 
+0

沒有,對不起,我想我沒有正確短語我一句。我沒有路徑,我正在使用readlink(「/ proc/self/exe」,buf,bufsize);正確地爲了檢索它。 – 2011-04-02 21:35:22

+0

我不明白你在說什麼。請編輯你的問題,以顯示你有什麼,以及你想要什麼的例子。 – Mat 2011-04-02 21:39:01

+0

我剛剛編輯了一個解釋。 – 2011-04-02 21:49:07

4

我們來看看the manpage說的是什麼:

readlink() places the contents of the symbolic link path in the buffer 
buf, which has size bufsiz. readlink does not append a NUL character to 
buf. 

好的。應該很簡單。鑑於你的1024個字符緩衝區:

char buf[1024]; 

/* The manpage says it won't null terminate. Let's zero the buffer. */ 
memset(buf, 0, sizeof(buf)); 

/* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */ 
if (readlink("/proc/self/exe", buf, sizeof(buf)-1) < 0) 
{ 
    /* There was an error... Perhaps the path does not exist 
    * or the buffer is not big enough. errno has the details. */ 
    perror("readlink"); 
    return -1; 
} 
+0

應該不是... if(readlink(「/ proc/self/exe」,buf,sizeof(buf)-1) – 2014-08-02 03:06:26

+0

'if(readlink(/*...*/))'測試非零值。小於0非零。 – asveikau 2014-08-02 03:48:53

+1

readlink在成功時返回> 0。 「成功時,readlink()返回放入buf的字節數,出錯時返回-1。」 http://linux.die.net/man/2/readlink。 – 2014-08-02 07:38:48

1
char * 
readlink_malloc (const char *filename) 
{ 
    int size = 100; 
    char *buffer = NULL; 

    while (1) 
    { 
     buffer = (char *) xrealloc (buffer, size); 
     int nchars = readlink (filename, buffer, size); 
     if (nchars < 0) 
     { 
      free (buffer); 
      return NULL; 
     } 
     if (nchars < size) 
     return buffer; 
     size *= 2; 
    } 
} 

來自http://www.delorie.com/gnu/docs/glibc/libc_279.html

1

接受的答案几乎是正確的,但你不能依賴PATH_MAX,因爲它是

不能保證如果系統不具有這樣的限制,則根據POSIX來定義。

(摘自的readlink(2)聯機幫助頁)

而且,當它被定義它並不總是代表 「真實」 的限制。 (見http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html

的的readlink的手冊頁也給出了辦法做到這一點的符號鏈接:

使用靜態大小的緩衝區可能無法提供足夠的空間 符號鏈接的內容。緩衝區所需的大小可以是 ,該值是從調用鏈接上的lstat(2)012th返回的stat.st_size值中獲得的。但是,應檢查readlink()和read- linkat()寫入的字節數,以確保在調用之間符號鏈接的大小不會增加。

但是在/ proc /自/ EXE的情況下,/爲大部分的/ proc文件,stat.st_size將爲0剩下的唯一解決方案,我看是調整緩衝區,而它不適合。

我建議使用vector<char>爲遵循這一目的:

std::string get_selfpath() 
{ 
    std::vector<char> buf(400); 
    ssize_t len; 

    do 
    { 
     buf.resize(buf.size() + 100); 
     len = ::readlink("/proc/self/exe", &(buf[0]), buf.size()); 
    } while (buf.size() == len); 

    if (len > 0) 
    { 
     buf[len] = '\0'; 
     return (std::string(&(buf[0]))); 
    } 
    /* handle error */ 
    return ""; 
}