How to get the executable directory of a C program using the independent plataform method?

I am developing my application on Linux for both unix and win32 (cross-compiling on each build), so the ready-to-use function will be nice :). I use glib, which has a function gchar* g_get_current_dir(void), and returns the current directory, but I really need an executable directory. I am inexperienced in C programming, so any suggestions are welcome.

+3
source share
3 answers

On Unix, such as operating systems that have a directory /proc, you can readlink /proc/self/exeget the full path to the executable files, even if it argv[0]does not.

However, this may not work if the executable was launched using fexecv(not available for many systems), and if it is implemented as a system call on your system. fexecvit is similar execve, except that it is passed the handle of the open file, and not the name of the file to run. On Linux, it is implemented by calling execveon the line generated by `` / proc / self /% i ", fd", so the file had to live on the file system when the program started.

I think GNU / Hurd supports it fexecvenatively.

, , , , ​​ ( , ).

+1

GetModuleFileName Windows. argv [0] linux

.. - , -, (Qt, wxWidgets, ACE, Boost [ , , - ]...)

+1

. UNIX, , . exec , , , , , , "../../../mybin/exe/myprogram". PATH .

: , , , ? . getcwd(), , , . , .

, , !

a call from main is required using argv [0], I use popen () calls to the shell to make the code suitable in small, popen () is not always an excellent choice, this can be unsuccessful if there are other executables earlier in PATH so same name:

char *
mypath(const char *src)
{
   FILE *cmd=NULL;
   static char path_2_me[PATH_MAX]={0x0};
   char tmp[PATH_MAX]={0x0};
   const char *basename=strrchr(src, '/');

   if(basename==NULL) 
        basename=src;
   else
        basename++;      

   if(memcmp(src, "./", 2)==0)      
     sprintf(path_2_me,"%s/%s", getcwd(tmp, PATH_MAX), basename);             
   else
   {
      sprintf(tmp, "/usr/bin/which %s", basename);
      cmd=popen(tmp, "r");      
      fgets(path_2_me, sizeof(path_2_me), cmd); /* one read only */
      pclose(cmd);
      /* check for what your version of which says on failure */
      if(memcmp(path_2_me, "no ", 3)==0)
         *path_2_me=0x0;
   }  

   return (*path_2_me) ?path_2_me: NULL;
}
0
source

Source: https://habr.com/ru/post/1749585/


All Articles