3

I'm using GTK to create an interface for my C program running Linux.

I'm using this function to load my XML interface:

gtk_builder_add_from_file(builder, g_build_filename("myInterface.glade", NULL), &error);

As long as I'm in the same directory as my compiled file, it works. But if I'm in another directory, let say a child one and I execute it: ../a.out, my program doesn't find the file.

So the idea is to first get the program path ("/home/.../program") and to add the file name to get an absolute path.

But I have no idea how can I get the program path. And I'm not sure this is the best idea to make it work.

Any idea? Thanks!

Florian
  • 372
  • 2
  • 12
Adrien Neveu
  • 827
  • 1
  • 15
  • 28
  • On which OS you need this? – alk Sep 28 '14 at 11:02
  • 2
    The answers so far do not consider the case when the executbale was started with no path given, but was found by the shell via scanning the `PATH` environment variable. – alk Sep 28 '14 at 11:06
  • 2
    Related if OS is Linux: http://stackoverflow.com/q/606041/694576 – alk Sep 28 '14 at 11:07
  • dirname() in libgen.h allows me to get the path of argv[0] and concatenate my file path to it. This was what I needed. – Adrien Neveu Sep 28 '14 at 11:13
  • I've got some code [here](http://code.google.com/p/xpost/source/browse/src/bin/xpost_pathname.c) that tries to do this. – luser droog Sep 28 '14 at 11:57
  • @luserdroog For Windows you can use [GetModuleFileName](http://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx) without any further issues. – MicroVirus Sep 28 '14 at 21:07
  • You can't in general (because the C standard does not know about paths or directories). On *some* operating systems, you could use OS specific tricks. – Basile Starynkevitch Sep 30 '14 at 12:50

2 Answers2

2

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);
    }
}
Shlomi Agiv
  • 1,183
  • 7
  • 17
  • 4
    `argv[0]` contains the name by which the program was called. You cannot rely on the full path being in it. – MicroVirus Sep 28 '14 at 10:49
  • This is still abusing the argument vector and unreliable as a solution for the question. argv[0] is just the invoked program name: it might include a relative path, it might include a full path, it might not include any path at all. – Jussi Kukkonen Sep 29 '14 at 09:21
  • You have a point in that, yet for most cases, it's a good solution. I use it all the time, so if there is some better solution, I'd love to know. – Shlomi Agiv Sep 30 '14 at 10:45
1

In your case where you are using GTK, it is better to use GResource and compile myInterface.glade directly into your program.

ptomato
  • 56,175
  • 13
  • 112
  • 165