tags:

views:

148

answers:

5

Possible Duplicate:
how to find the location of the executable in C

I would like an executable to be able to discover its own path; I have a feeling that the answer is "you can't do this", but I would like this to be confirmed!

I don't think I can use getcwd(), because I might not be executing it from the same directory. I don't think I can use argv[0], because that is based on the string that's used to execute it. Are there any other options?

Rationale

The real problem is that I'd like to place an executable somewhere on a filesystem, and place a default config file alongside it. I want the executable to be able to read its config file at runtime, but I don't want to hardcode this location into the executable, nor do I want the user to have to set environment variables. If there's a better solution to this situation, I'm all ears...

+1  A: 

Well, you have to use getcwd() in conjuction with argv[0]. The first one gives you the working directory, the second one gives you the relative location of the binary from the working directory (or an absolute path).

Let_Me_Be
and why downvote this one too? someone's being lame..
SB
@Let_Me_Be: I didn't downvote, but I don't think this works. `argv[0]` is not necessarily relative (consider running executable from command-line as `/blah/my_app`).
Oli Charlesworth
Programs to run not searched in cwd, but in $PATH, until you specify path to executable.
Vovanium
+5  A: 

Use the proc filesystem

Your flow would be:

  • Get pid of executable
  • look at /proc/PID/exe for a symlink
SB
why the downvote? and why only downvote mine when CodeninjaTim basically says the same thing?
SB
+2  A: 

You can use getpid() to find the pid of the current process, then read /proc//cmdline (for a human reader) or /proc//exe which is a symlink to the actual program. Then, using readlink(), you can find the full path of the program.

Here is an implementation in C:

#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>

int main()
{
  char path[PATH_MAX];
  char dest[PATH_MAX];
  struct stat info;
  pid_t pid = getpid();
  sprintf(path, "/proc/%d/exe", pid);
  if (readlink(path, dest, PATH_MAX) == -1)
    perror("readlink");
  else {
    printf("%s\n", dest);
  }
  return 0;
}

If you want to try, you can then compile this, make a symlink from the executable to an other path, and call the link:

$ gcc -o mybin source.c
$ ln -s ./mybin /tmp/otherplace
$ /tmp/otherplace
/home/fser/mybin
Aif
+1  A: 

Get your name from argv[0] then call out to the which command. This will obv only work if your executable is in $PATH.

Gaius
+7  A: 

The file /proc/self/exe is a simlink to the currently running executable.

CodeninjaTim
This symlink should be read with readlink.
Aif