Bene, devi usare getcwd() in combinazione con argv[0] . Il primo ti dà la directory di lavoro, il secondo ti dà la posizione relativa del binario dalla directory di lavoro (o un percorso assoluto).
 Modifica: È stato sottolineato che l'utilizzo di /proc/self/exe è più semplice. Questo è del tutto vero, ma non ho visto alcun vantaggio nella modifica del codice. Dato che ricevo ancora commenti al riguardo, l'ho modificato.
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
int main()
{
  char dest[PATH_MAX];
  memset(dest,0,sizeof(dest)); // readlink does not null terminate!
  if (readlink("/proc/self/exe", dest, PATH_MAX) == -1) {
    perror("readlink");
  } else {
    printf("%s\n", dest);
  }
  return 0;
}
 Risposta iniziale: Puoi usare getpid() per trovare il pid del processo corrente, quindi leggere /proc/<pid>/cmdline (per un lettore umano) o /proc/<pid>/exe che è un collegamento simbolico al programma vero e proprio. Poi, usando readlink(), puoi trovare il percorso completo del programma.
Ecco un'implementazione in C:
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
int main()
{
  char path[PATH_MAX];
  char dest[PATH_MAX];
  memset(dest,0,sizeof(dest)); // readlink does not null terminate!
  pid_t pid = getpid();
  sprintf(path, "/proc/%d/exe", pid);
  if (readlink(path, dest, PATH_MAX) == -1) {
    perror("readlink");
  } else {
    printf("%s\n", dest);
  }
  return 0;
}
Se vuoi provare, puoi quindi compilare questo, creare un collegamento simbolico dall'eseguibile a un altro percorso e chiamare il collegamento:
$ gcc -o mybin source.c
$ ln -s ./mybin /tmp/otherplace
$ /tmp/otherplace
/home/fser/mybin
Usa il filesystem proc
Il tuo flusso sarebbe:
- Ottieni pid dell'eseguibile
- guarda /proc/PID/exeper un collegamento simbolico
Il file /proc/self/exe è un simlink all'eseguibile attualmente in esecuzione.