2011-04-02 157 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 ""; 
}