chdir() to where the binary is running from before doing anything else.
authorRyan C. Gordon <icculus@icculus.org>
Tue, 08 Jul 2014 23:47:17 -0400
changeset 39 ddb45e88adc9
parent 38 115b6a0bd0af
child 40 3c2fddfada9f
chdir() to where the binary is running from before doing anything else.

This is so we can find our script files, etc, regardless of where the
program is run from.

Note that this means your 1Password symlink needs to live where the binary
does, at least until we let you specify one elsewhere.
1pass.c
--- a/1pass.c	Thu May 01 01:13:24 2014 -0400
+++ b/1pass.c	Tue Jul 08 23:47:17 2014 -0400
@@ -623,8 +623,62 @@
 } // initSignals
 
 
+// this was from PhysicsFS ( https://icculus.org/physfs/ ), zlib license.
+static char *readSymLink(const char *path)
+{
+    ssize_t len = 64;
+    ssize_t rc = -1;
+    char *retval = NULL;
+
+    while (1)
+    {
+         char *ptr = (char *) realloc(retval, (size_t) len);
+         if (ptr == NULL)
+             break;   // out of memory.
+         retval = ptr;
+
+         rc = readlink(path, retval, len);
+         if (rc == -1)
+             break;  // not a symlink, i/o error, etc.
+
+         else if (rc < len)
+         {
+             retval[rc] = '\0';  // readlink doesn't null-terminate.
+             return retval;  // we're good to go.
+         } // else if
+
+         len *= 2;  // grow buffer, try again.
+    } // while
+
+    if (retval != NULL)
+        free(retval);
+    return NULL;
+} // readSymLink
+
+
+static void chdirToApp(void)
+{
+    char *ptr;
+    char *path = readSymLink("/proc/self/exe");
+    
+    if (path == NULL)
+        return;  // maybe we're already there, fail later if not.
+
+    ptr = strrchr(path, '/');
+    if (ptr != NULL)
+    {
+        *ptr = '\0';
+        if (chdir(path) == -1)
+            fprintf(stderr, "Couldn't chdir() to app directory?! %s\n", strerror(errno));
+    } // if
+
+    free(path);
+} // chdirToApp
+
+
 int main(int argc, char **argv)
 {
+    chdirToApp();
     initSignals();
     initPowermate(&argc, argv);
     gtk_init(&argc, &argv);