How to get the executable path with getcwd when called from a symbolic link in C

advertisements

Say I have a program, abc in Linux, with a method:

char *currentPath(){
        char *path=NULL;
        path = getcwd(path, MAXPATHLEN);
        return path;
}

When calling abc directly, this path returns the path that abc is in.

If I make a symbolic link to abc, and call the symbolic link, currentPath() returns the path of the symbolic link.

Is there a way to get make this method return the path of abc? I am interested in accessing files relative to the location of abc.


You can't use getcwd() to help get the executable name; it is not a sensible way to go about finding the pathname of the executable.

On Linux, there is a symlink /proc/self/exe that gives you the name of the executable if you read it with the readlink() system call. Beware, the readlink() system call does not null terminate the value it returns (and I have no idea why not; it is singularly weird behaviour in my book, and an instant cause of bugs for the unwary).

There are a number of problems with your scheme.

  1. If the program is found via $PATH, there's no guarantee that the current directory is the same as the directory containing the executable. If you think about it, you run /bin/ls without having to be in the /bin directory.
  2. If you're worried about security, be aware that the value of argv[0] is under the control of the program launching the target program. The shell behaves nicely; other programs may be more malicious:

    #include <unistd.h>
    int main(void)
    {
        char *argv[] = { "/opt/you/bin/bogus", "300", 0 };
        execvp("sleep", argv);
        return(-1);
    }
    
    

    This passes the program name as /opt/you/bin/bogus even though it invokes the program sleep.

If you search the web, you will find plenty of examples of 'how to get the executable name' that assume that argv[0] is the way to go; it is not. Other platforms have other techniques for getting to the executable name. Using /proc/self/exe is not portable; neither are the other techniques.