How to Find The Full Path of The C++ Linux Program from Within

How do I find the location of the executable in C?

To summarize:

  • On Unixes with /proc really straight and realiable way is to:

    • readlink("/proc/self/exe", buf, bufsize) (Linux)

    • readlink("/proc/curproc/file", buf, bufsize) (FreeBSD)

    • readlink("/proc/self/path/a.out", buf, bufsize) (Solaris)

  • On Unixes without /proc (i.e. if above fails):

    • If argv[0] starts with "/" (absolute path) this is the path.

    • Otherwise if argv[0] contains "/" (relative path) append it to cwd
      (assuming it hasn't been changed yet).

    • Otherwise search directories in $PATH for executable argv[0].

    Afterwards it may be reasonable to check whether the executable isn't actually a symlink.
    If it is resolve it relative to the symlink directory.

    This step is not necessary in /proc method (at least for Linux).
    There the proc symlink points directly to executable.

    Note that it is up to the calling process to set argv[0] correctly.
    It is right most of the times however there are occasions when the calling process cannot be trusted (ex. setuid executable).

  • On Windows: use GetModuleFileName(NULL, buf, bufsize)

How to find the full path of the C++ Linux program from within?

On Linux (Posix?) you have a symbolic link /proc/self/exe which links to the full path of the executable.

On Windows, use GetModuleFileName.

Never rely on argv[0], which is not guaranteed to be anything useful.

Note that paths and file systems are not part of the language and thus necessarily a platform-dependent feature.

How can I get the application path in C?

argv[0] contain the relative/full path you ran to run the program.

just scan up to the last '/' and this will be the run dir from your current location

'edit' after some more research, i found this, which works in all cases:

#include<stdio.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
int main()
{
char path[500] = {0};
int dest_len = 500;
if (readlink ("/proc/self/exe", path, dest_len) != -1)
{
dirname (path);
strcat (path, "/");
printf("path=%s\n", path);
}
}

How to find the full pathname of a binary within C?

Use execlp or execvp instead of execl or execvp. The p versions of these calls search PATH to find the executable if it doesn't contain any slashes.

Get current path when C app is launched from /bin/ in Linux

If you want to get the directory the process was run from you can use the system call getcwd to copy a string into a buffer and return it. The kernel keeps track of this for every process.

e.g.

char buf[100];
printf("Current directory: %s\n", getcwd(buf, 100));

The working directory can be changed, but will default to where the process launched.

Getting the full path of a running PID with C/C++ without using the system function (Linux)

Use readlink("/proc/<pid>/exe", buf, bufsize) to get the path to <pid>'s executable. This works on Linux, provided procfs is available (it usually is).

Example usage:

int get_exe_for_pid(pid_t pid, char *buf, size_t bufsize) {
char path[32];
sprintf(path, "/proc/%d/exe", pid);
return readlink(path, buf, bufsize);
}

Returns -1 on failure and sets errno.

How do I get the directory that a program is running from?

Here's code to get the full path to the executing app:

Variable declarations:

char pBuf[256];
size_t len = sizeof(pBuf);

Windows:

int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;

Linux:

int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
pBuf[bytes] = '\0';
return bytes;

In C on a *nix system, find a binary's absolute path with $PATH or which?

The first method (using getenv("PATH") and scanning it....) is preferable and more efficient... This is often what which usually does (but don't depend on which whose behavior can vary a lot...) but you won't fork(2) any process (and fork or system or which may fail).

However, I question why you need to find the path of some executable. You could simply use execvp(3) (and similar exec*p* functions, all of them doing the equivalent of getenv("PATH"), then scanning it like you would, internally before execve(2)) when executing that program.

(In very pathological cases which you are right to ignore, the getenv("PATH") could fail)

Notice that the binary executable could be removed (or added, or corrupted...) between the moment when you test its existence (and find it in PATH) and the moment you are execve(2)-ing it. And that execve can fail (rarely) for many reasons, or not work as you expect (in particular, if some shared library on which your 7z executable depends is corrupted or removed).

Don't forget that on Linux, several processes could read and write (or execute) the same file (which could also be removed or renamed while it is read). Please read more about i-nodes.

Hence, finding the full path of 7z before execvp-ing it is wrong -or inaccurate: some other program could have removed or reinstalled 7z after the path check and before its execve(2). I don't understand why you want to scan the PATH, and I believe it is generally useless, leave that to execvp

See also wordexp(3), glob(3), glob(7)

Since most software on Linux distributions are free software, you can (and perhaps you should) study their source code. For which it is often a builtin of your shell (and bash, zsh, fish are all free software), or a program from debianutils (perhaps not coreutils), and I am not sure that most distributions have it (and some of them won't install it by default).

PS. My feeling is that your code should not use 7z which is usually not available on most Linux systems - and not on my systems; you are perhaps implicitly requiring your user to install it (at least document that). You might prefer tar archives to zip ones, notice that tar.h is a POSIX header! See this question and consider libtar

How to get the current directory in a C program?

Have you had a look at getcwd()?

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

Simple example:

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

int main() {
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("Current working dir: %s\n", cwd);
} else {
perror("getcwd() error");
return 1;
}
return 0;
}


Related Topics



Leave a reply



Submit