srcanamdw/codescanner/pyinstaller/source/linux/getpath.c
changeset 1 22878952f6e2
equal deleted inserted replaced
0:509e4801c378 1:22878952f6e2
       
     1 /***********************************************************
       
     2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
       
     3 The Netherlands.
       
     4 
       
     5                         All Rights Reserved
       
     6 
       
     7 Permission to use, copy, modify, and distribute this software and its
       
     8 documentation for any purpose and without fee is hereby granted,
       
     9 provided that the above copyright notice appear in all copies and that
       
    10 both that copyright notice and this permission notice appear in
       
    11 supporting documentation, and that the names of Stichting Mathematisch
       
    12 Centrum or CWI or Corporation for National Research Initiatives or
       
    13 CNRI not be used in advertising or publicity pertaining to
       
    14 distribution of the software without specific, written prior
       
    15 permission.
       
    16 
       
    17 While CWI is the initial source for this software, a modified version
       
    18 is made available by the Corporation for National Research Initiatives
       
    19 (CNRI) at the Internet address ftp://ftp.python.org.
       
    20 
       
    21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
       
    22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
       
    23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
       
    24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
       
    25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
       
    26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
       
    27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
       
    28 PERFORMANCE OF THIS SOFTWARE.
       
    29 
       
    30 ******************************************************************/
       
    31 
       
    32 /* A special version for minimal installs, where
       
    33    the bootstrap path is the directory in which
       
    34    the executable lives.
       
    35    Gordon McMillan, McMillan Enterprises, Inc. */
       
    36 
       
    37 /* Return the initial module search path. */
       
    38 
       
    39 #include "Python.h"
       
    40 #include "osdefs.h"
       
    41 
       
    42 #include <sys/types.h>
       
    43 #include <sys/stat.h>
       
    44 #include <string.h>
       
    45 
       
    46 #if HAVE_UNISTD_H
       
    47 #include <unistd.h>
       
    48 #endif /* HAVE_UNISTD_H */
       
    49 
       
    50 #ifdef WITH_NEXT_FRAMEWORK
       
    51 #include <mach-o/dyld.h>
       
    52 #endif
       
    53 
       
    54 static char prefix[MAXPATHLEN+1];
       
    55 static char *exec_prefix;
       
    56 static char progpath[MAXPATHLEN+1];
       
    57 static char *module_search_path = NULL;
       
    58 
       
    59 static void
       
    60 reduce(char *dir)
       
    61 {
       
    62 	int i = strlen(dir);
       
    63 	while (i > 0 && dir[i] != SEP)
       
    64 		--i;
       
    65 	dir[i] = '\0';
       
    66 }
       
    67 
       
    68 
       
    69 #ifndef S_ISREG
       
    70 #define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
       
    71 #endif
       
    72 
       
    73 #ifndef S_ISDIR
       
    74 #define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
       
    75 #endif
       
    76 #if 0
       
    77 static int
       
    78 isfile(char *filename)		/* Is file, not directory */
       
    79 {
       
    80 	struct stat buf;
       
    81 	if (stat(filename, &buf) != 0)
       
    82 		return 0;
       
    83 	if (!S_ISREG(buf.st_mode))
       
    84 		return 0;
       
    85 	return 1;
       
    86 }
       
    87 #endif
       
    88 #if 0
       
    89 static int
       
    90 ismodule(char *filename)		/* Is module -- check for .pyc/.pyo too */
       
    91 {
       
    92 	if (isfile(filename))
       
    93 		return 1;
       
    94 
       
    95 	/* Check for the compiled version of prefix. */
       
    96 	if (strlen(filename) < MAXPATHLEN) {
       
    97 		strcat(filename, Py_OptimizeFlag ? "o" : "c");
       
    98 		if (isfile(filename))
       
    99 			return 1;
       
   100 	}
       
   101 	return 0;
       
   102 }
       
   103 #endif
       
   104 
       
   105 static int
       
   106 isxfile(char *filename)		/* Is executable file */
       
   107 {
       
   108 	struct stat buf;
       
   109 	if (stat(filename, &buf) != 0)
       
   110 		return 0;
       
   111 	if (!S_ISREG(buf.st_mode))
       
   112 		return 0;
       
   113 	if ((buf.st_mode & 0111) == 0)
       
   114 		return 0;
       
   115 	return 1;
       
   116 }
       
   117 
       
   118 #if 0
       
   119 static int
       
   120 isdir(char *filename)			/* Is directory */
       
   121 {
       
   122 	struct stat buf;
       
   123 	if (stat(filename, &buf) != 0)
       
   124 		return 0;
       
   125 	if (!S_ISDIR(buf.st_mode))
       
   126 		return 0;
       
   127 	return 1;
       
   128 }
       
   129 #endif
       
   130 
       
   131 static void
       
   132 joinpath(char *buffer, char *stuff)
       
   133 {
       
   134 	int n, k;
       
   135 	if (stuff[0] == SEP)
       
   136 		n = 0;
       
   137 	else {
       
   138 		n = strlen(buffer);
       
   139 		if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
       
   140 			buffer[n++] = SEP;
       
   141 	}
       
   142 	k = strlen(stuff);
       
   143 	if (n + k > MAXPATHLEN)
       
   144 		k = MAXPATHLEN - n;
       
   145 	strncpy(buffer+n, stuff, k);
       
   146 	buffer[n+k] = '\0';
       
   147 }
       
   148 
       
   149 static void
       
   150 calculate_path(void)
       
   151 {
       
   152 	char *prog = Py_GetProgramName();	/* use Py_SetProgramName(argv[0]) before Py_Initialize() */
       
   153 	char argv0_path[MAXPATHLEN+1];
       
   154 	char *epath;
       
   155 	char *path = NULL;
       
   156 	char *ppath = NULL;
       
   157         int  numchars;
       
   158 
       
   159 	if (strchr(prog, SEP))
       
   160 		strcpy(progpath, prog);
       
   161 	else {
       
   162 #if HAVE_READLINK
       
   163             sprintf(argv0_path, "/proc/%d/exe", getpid());
       
   164             numchars = readlink(argv0_path, progpath, MAXPATHLEN);
       
   165             if (numchars > 0) 
       
   166                 progpath[numchars] = '\0';
       
   167             else {
       
   168 #endif
       
   169 		epath = getenv("PATH");
       
   170                 if (epath) 
       
   171                     path = malloc(strlen(epath)+3);
       
   172 		if (path) {
       
   173                     strcpy(path, ".:");
       
   174                     strcat(path, epath);
       
   175 		    ppath = path;
       
   176 	    	    while (1) {
       
   177 				char *delim = strchr(ppath, DELIM);
       
   178 
       
   179 				if (delim) {
       
   180 					int len = delim - ppath;
       
   181 					strncpy(progpath, ppath, len);
       
   182 					*(progpath + len) = '\0';
       
   183 				}
       
   184 				else
       
   185 					strcpy(progpath, ppath);
       
   186 
       
   187 				joinpath(progpath, prog);
       
   188 				if (isxfile(progpath))
       
   189 					break;
       
   190 
       
   191 				if (!delim) {
       
   192 					progpath[0] = '\0';
       
   193 					break;
       
   194 				}
       
   195 				ppath = delim + 1;
       
   196 		    }
       
   197                     free(path);
       
   198 		}
       
   199 		else
       
   200 			progpath[0] = '\0';
       
   201 #if HAVE_READLINK
       
   202             }
       
   203 #endif
       
   204 	}
       
   205 	/* at this point progpath includes the executable */
       
   206 	strcpy(argv0_path, progpath);
       
   207 	
       
   208 #if HAVE_READLINK
       
   209 	{
       
   210 		char tmpbuffer[MAXPATHLEN+1];
       
   211 		int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
       
   212 		while (linklen != -1) {
       
   213 			/* It's not null terminated! */
       
   214 			tmpbuffer[linklen] = '\0';
       
   215 			if (tmpbuffer[0] == SEP)
       
   216 				strcpy(argv0_path, tmpbuffer);
       
   217 			else {
       
   218 				/* Interpret relative to progpath */
       
   219 				reduce(argv0_path);
       
   220 				joinpath(argv0_path, tmpbuffer);
       
   221 			}
       
   222 			linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
       
   223 		}
       
   224                 strcpy(progpath, argv0_path);
       
   225 	}
       
   226 #endif /* HAVE_READLINK */
       
   227 
       
   228 	reduce(argv0_path);
       
   229 	/* now argv0_path is the directory of the executable */
       
   230 
       
   231 	strcpy(prefix, argv0_path);
       
   232 	exec_prefix = prefix;
       
   233 	module_search_path = malloc(strlen(prefix)+1);
       
   234 	strcpy(module_search_path, prefix);
       
   235 
       
   236 }
       
   237 /* External interface */
       
   238 
       
   239 char *
       
   240 Py_GetPath(void)
       
   241 {
       
   242 	if (!module_search_path)
       
   243 		calculate_path();
       
   244 	return module_search_path;
       
   245 }
       
   246 
       
   247 char *
       
   248 Py_GetPrefix(void)
       
   249 {
       
   250 	if (!module_search_path)
       
   251 		calculate_path();
       
   252 	return prefix;
       
   253 }
       
   254 
       
   255 char *
       
   256 Py_GetExecPrefix(void)
       
   257 {
       
   258 	if (!module_search_path)
       
   259 		calculate_path();
       
   260 	return exec_prefix;
       
   261 }
       
   262 
       
   263 char *
       
   264 Py_GetProgramFullPath(void)
       
   265 {
       
   266 	if (!module_search_path)
       
   267 		calculate_path();
       
   268 	return progpath;
       
   269 }