diff -ru Python-2.7.2_orig//Modules/getpath.c Python-2.7.2/Modules/getpath.c --- Python-2.7.2_orig//Modules/getpath.c 2011-06-11 08:46:27.000000000 -0700 +++ Python-2.7.2/Modules/getpath.c 2011-10-15 14:59:36.506927561 -0700 @@ -486,22 +486,59 @@ #if HAVE_READLINK { + int haslink = 0; char tmpbuffer[MAXPATHLEN+1]; - int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); - while (linklen != -1) { - /* It's not null terminated! */ - tmpbuffer[linklen] = '\0'; - if (tmpbuffer[0] == SEP) - /* tmpbuffer should never be longer than MAXPATHLEN, - but extra check does not hurt */ - strncpy(argv0_path, tmpbuffer, MAXPATHLEN); - else { - /* Interpret relative to progpath */ - reduce(argv0_path); - joinpath(argv0_path, tmpbuffer); + char tmpbuffer2[MAXPATHLEN+1]; + char pathaccum[MAXPATHLEN+1]; + + /* path accum starts out empty */ + pathaccum[0] = '\0'; + + /* initialize tmpbuffer2 with progpath */ + strncpy(tmpbuffer2, progpath, MAXPATHLEN); + + /* iterator over tmpbuffer2 until it is empty */ + while( tmpbuffer2[0] != '\0' ) + { + int linklen = readlink(tmpbuffer2, tmpbuffer, MAXPATHLEN); + while (linklen != -1) { + haslink = 1; + /* It's not null terminated! */ + tmpbuffer[linklen] = '\0'; + if (tmpbuffer[0] == SEP) + /* tmpbuffer should never be longer than MAXPATHLEN, + but extra check does not hurt */ + strncpy(tmpbuffer2, tmpbuffer, MAXPATHLEN); + else { + /* Interpret relative to progpath */ + reduce(tmpbuffer2); + joinpath(tmpbuffer2, tmpbuffer); + } + linklen = readlink(tmpbuffer2, tmpbuffer, MAXPATHLEN); + } + + /* The last path element in tmpbuffer2 is not a symlink, so + accumulate it. Get the basename of the path in tmpbuffer2 + and prepend it to pathaccum */ + { + size_t len = strlen(tmpbuffer2); + size_t i = len; + while( i > 0 && tmpbuffer2[i] != SEP ) + --i; + + /* save pathaccum into a temporary buffer */ + strncpy(tmpbuffer, pathaccum, MAXPATHLEN); + /* place the basename at the front of pathaccum */ + strncpy(pathaccum, &tmpbuffer2[i], len-i); + /* append the prior contents of pathaccum */ + strncpy(&pathaccum[len-i], tmpbuffer, MAXPATHLEN-(len-i)); } - linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); + /* chomp the path element on the end */ + reduce(tmpbuffer2); } + // Only modify argv0_path if symlinks were found in progpath + if( haslink ) + strncpy(argv0_path, pathaccum, MAXPATHLEN); } #endif /* HAVE_READLINK */