summarylogtreecommitdiffstats
path: root/0002-Allow-usr-bin-env-in-script.patch
blob: 6e1b5ca00d3948702a1b71db30ec5a0d8d795ebf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
--- setuptools-5.4.1/launcher.c.orig   2014-06-29 02:40:09.000000000 +0100
+++ setuptools-5.4.1/launcher.c        2014-10-19 13:37:21.272787900 +0100
@@ -104,9 +104,19 @@
 }
 
 
-char *find_exe(char *exename, char *script) {
+int file_exists(char* path)
+{
+    DWORD attrib = GetFileAttributes(path);
+
+    if ((attrib == INVALID_FILE_ATTRIBUTES) || (attrib & FILE_ATTRIBUTE_DIRECTORY)) return 0;
+    return 1;
+}
+
+char *find_exe(char *exename, char *script, int search_in_path) {
     char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
     char path[_MAX_PATH], c, *result;
+    char *path_env, *path_env_start;
+    int maximum, needs_exe = 0;
 
     /* convert slashes to backslashes for uniform search below */
     result = exename;
@@ -116,6 +126,34 @@
     if (drive[0] || dir[0]=='\\') {
         return loadable_exe(exename);   /* absolute path, use directly */
     }
+
+    if (search_in_path) {
+        if (strstr(exename, ".exe") == NULL) needs_exe = 1;
+        char *path_env = getenv("PATH");
+        while (path_env != NULL) {
+            path_env_start = path_env;
+            path_env = strchr(path_env, ';');
+            maximum = _MAX_PATH - 2 - strlen(exename) - (needs_exe * strlen(".exe"));
+            if (path_env == NULL) {
+                strncpy(path, path_env_start, maximum);
+            }
+            else {
+                maximum = path_env - path_env_start < maximum ? path_env - path_env_start : maximum;
+                memcpy(path, path_env_start, maximum);
+                ++path_env;
+            }
+            path[maximum] = '\0';
+            strcat(path, "\\");
+            strcat(path, exename);
+            if (needs_exe) strcat(path, ".exe");
+            /* printf("Checking %s\n", path); */
+            if (file_exists(path)) {
+                /* printf("Found\n"); */
+                return loadable_exe(path);
+            }
+        }
+    }
+
     /* Use the script's parent directory, which should be the Python home
        (This should only be used for bdist_wininst-installed scripts, because
         easy_install-ed scripts use the absolute path to python[w].exe
@@ -206,7 +244,7 @@
     // set-up control handler callback funciotn
     SetConsoleCtrlHandler((PHANDLER_ROUTINE) control_handler, TRUE);
     if (!CreateProcessA(NULL, commandline, NULL, NULL, TRUE, 0, NULL, NULL, &s_info, &p_info)) {
-        fprintf(stderr, "failed to create process.\n");
+        fprintf(stderr, "failed to create process (%s).\n", commandline);
         return 0;
     }   
     child_pid = p_info.dwProcessId;
@@ -256,6 +294,9 @@
     char *ptr, *end;    /* working pointers for string manipulation */
     char *cmdline;
     int i, parsedargc;              /* loop counter */
+    char *env, *first_space;
+    int skip = 2;
+    int search_in_path = 0;
 
     /* compute script name from our .exe name*/
     GetModuleFileNameA(NULL, script, sizeof(script));
@@ -284,12 +325,24 @@
         strcpy(python, "#!python.exe");
     }
 
-    parsedargs = parse_argv(python+2, &parsedargc);
+    /* Check if "env" appears before the first space and skip
+       ahead to the next space. */
+    env = strstr(python+skip, "env");
+    first_space = strchr(python+skip, ' ');
+    if (env != NULL && (first_space == NULL || env < first_space)) {
+        search_in_path = 1;
+        env += 3;
+        while (*env && *env != ' ')
+          ++env;
+        skip = env - python;
+    }
+
+    parsedargs = parse_argv(python+skip, &parsedargc);
 
     /* Using spawnv() can fail strangely if you e.g. find the Cygwin
        Python, so we'll make sure Windows can find and load it */
 
-    ptr = find_exe(parsedargs[0], script);
+    ptr = find_exe(parsedargs[0], script, search_in_path);
     if (!ptr) {
         return fail("Cannot find Python executable %s\n", parsedargs[0]);
     }