ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Yes, this is a bit of a problem in Linux, as argv[0] contains the commandline the program was started with. If you start your program specifying the full path of the executable, then argv[0] will contain the full path.
I've been puzzled by this as well, but I found two ways of getting the full path. It is a bit more complicated though.
Here are 2 examples of how to do this in C. I don't know enough about C++ to do it in proper C++. Anyways, you can use it (almost) unmodified in C++ I think.
Code:
/* getexepath1.c
* ~~~~~~~~~~~~~
* This uses the environment variable "_" to read
* the relative path of the executable.
* This is not available allways. I assume it's
* set by the shell, and not all do this.
* Anyways, using bash on linux or BSD it will work.
*
* From this relative path the full path can be
* resolved by the realpath() function.
* Which is also not reliable on all systems.
* (see BUGS section in "man 3 realpath")
* On linux it generally works OK.
*/
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main ()
{
char *exepath;
char fullpath[PATH_MAX+1];
if ((exepath = getenv("_")) == NULL) {
fprintf(stderr, "Could not read path from environment.\n");
exit(EXIT_FAILURE);
}
if (realpath(exepath, fullpath) == NULL) {
fprintf(stderr, "Error resolving full path.\n");
exit(EXIT_FAILURE);
}
printf("Path is: %s\n", exepath);
printf("Full path is: %s\n", fullpath);
return 0;
}
Code:
/* getexepath2.c
* ~~~~~~~~~~~~~
* This uses the /proc filesystem. This may be
* not available on all systems, but on Linux it
* usually is. However it is possible to compile
* a linux kernel that does not provide
* the /proc filesystem.
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#define MAXPATHLEN 200 /* make this larger if you need to. */
int main ()
{
int length;
char fullpath[MAXPATHLEN];
/* /proc/self is a symbolic link to the process-ID subdir
* of /proc, e.g. /proc/4323 when the pid of the process
* of this program is 4323.
*
* Inside /proc/<pid> there is a symbolic link to the
* executable that is running as this <pid>. This symbolic
* link is called "exe".
*
* So if we read the path where the symlink /proc/self/exe
* points to we have the full path of the executable.
*/
length = readlink("/proc/self/exe", fullpath, sizeof(fullpath));
/* Catch some errors: */
if (length < 0) {
fprintf(stderr, "Error resolving symlink /proc/self/exe.\n");
exit(EXIT_FAILURE);
}
if (length >= MAXPATHLEN) {
fprintf(stderr, "Path too long. Truncated.\n");
exit(EXIT_FAILURE);
}
/* I don't know why, but the string this readlink() function
* returns is appended with a '@'.
*/
fullpath[length] = '\0'; /* Strip '@' off the end. */
printf("Full path is: %s\n", fullpath);
return 0;
}
The file name that the link points to is copied into buffer. This file name string is not null-terminated.
That is why you see an @ there. It must be manually null terminated.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
#define zout(z) memset(z,0x00,sizeof(z))
/* calls to get the current working directory
one of these will work: getcwd() is POSIX
char *getcwd(char *buf,size_t size);
These other calls are prototyped only some circumstances:
char *get_current_dir_name(void);
char *getwd(char *buf);
****/
int main(int argc, char *argv[]){
char dirname[PATH_MAX+1];
zout(dirname);
if( getcwd(dirname,sizeof(dirname))!=NULL) printf("%s\n",dirname);
return 0;
}
I'm not sure, but I don't think getcwd is quite what was wanted here. As I understand it, the original poster wanted to know the path to his app. The current working diretory is not necessarily where that app resides. For instance, if you had your app somewhere in the path (e.g. /usr/local/bin) and were in your home directory when you executed it, your current working directory would be ~, not /usr/local/. Or if you had an app in ~/myapps/app, and just executed it from the ~ directory by giving the path to it...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.