This is the code we used in CivCTP.
It is Linux specific, and has a subtle bug for which I will post a fix on
Monday.
Enjoy! 
/*
This function gets the directory containing the running program.
argv0 - the 0āth argument to the program
runpath - the buffer for the final run path
runpathlen - the size of the buffer for the output
Warning: This function has lots of buffer overflows.
*/
char *loki_getrundirectory(char *argv0, char *runpath, int runpathlen)
{
char temppath[MAXPATHLEN];
char fullpath[MAXPATHLEN];
char *spot;
struct stat sb;
strcpy(temppath, argv0); /* If this overflows, it's your own fault :) */
if ( strrchr(temppath, '/') == NULL ) {
char *path = getenv("PATH");
while ( path ) {
char *PATHspot = strchr(path, ':');
if ( PATHspot ) {
*PATHspot = '\0';
}
if ( (!PATHspot && *path) || (PATHspot > (path+1)) ) {
if ( (*path == '~') && getenv("HOME") ) {
sprintf(temppath, "%s/%s/%s", getenv("HOME"),path+1,argv0);
} else {
sprintf(temppath, "%s/%s", path, argv0);
}
} else {
sprintf(temppath, "./%s", argv0);
}
path = PATHspot+1;
if ( (access(temppath, X_OK) == 0) &&
(stat(temppath, &sb) == 0) && S_ISREG(sb.st_mode) ) {
path = NULL;
}
if ( ! PATHspot ) {
/* At the end of PATH, and we haven't found our program? */
strcpy(temppath, argv0);
path = NULL;
} else {
*PATHspot = ':';
}
}
}
/* Now canonicalize it to a full pathname and return directory portion */
if ( realpath(temppath, fullpath) ) {
/* There should always be '/' in the path */
*(strrchr(fullpath, '/')) = '\0';
if ( strlen(fullpath) < runpathlen ) {
strcpy(runpath, fullpath);
} else {
runpath = NULL;
}
} else {
runpath = NULL;
}
return(runpath);
}
#ifdef __TEST_MAIN
int main(int argc, char *argv[])
{
printf(āOld pathname: %s\nā, argv[1]);
printf(āNew pathname: %s\nā, loki_canonical_path(argv[1]));
}
#endif
I think something like this should go into the FAQ.
It should be made cross-platform first. 
-Sam Lantinga (slouken at devolution.com)
Lead Programmer, Loki Entertainment Softwareā
āAny sufficiently advanced bug is indistinguishable from a featureā
ā Rich Kulawiec