Gentoo Archives: gentoo-python

From: "Michał Górny" <mgorny@g.o>
To: gentoo-python@l.g.o
Cc: python@g.o, "Michał Górny" <mgorny@g.o>
Subject: [gentoo-python] [PATCH 4/4] Remove python-wrapper
Date: Sun, 15 Nov 2015 09:39:37
Message-Id: 1447580355-16777-5-git-send-email-mgorny@gentoo.org
In Reply to: [gentoo-python] [eselect-python] Patches to switch to full python-exec wrapping by "Michał Górny"
1 ---
2 Makefile.am | 3 -
3 configure.ac | 26 ------
4 python-wrapper.c | 244 -------------------------------------------------------
5 3 files changed, 273 deletions(-)
6 delete mode 100644 python-wrapper.c
7
8 diff --git a/Makefile.am b/Makefile.am
9 index 06f7d1c..beb4029 100644
10 --- a/Makefile.am
11 +++ b/Makefile.am
12 @@ -1,5 +1,2 @@
13 -bin_PROGRAMS = python-wrapper
14 -python_wrapper_CPPFLAGS = -DENVD='"$(sysconfdir)/env.d"'
15 -
16 eselectdir = $(datadir)/eselect/modules
17 nodist_eselect_DATA = python.eselect
18 diff --git a/configure.ac b/configure.ac
19 index dc142ae..e782129 100644
20 --- a/configure.ac
21 +++ b/configure.ac
22 @@ -1,36 +1,10 @@
23 AC_INIT([eselect-python], [20140125])
24 AM_INIT_AUTOMAKE([-Wall foreign no-dist-gzip dist-bzip2])
25
26 -AC_PROG_CC
27 AC_PATH_PROG(INSTALL, install)
28 AC_PROG_MKDIR_P
29
30 -AC_USE_SYSTEM_EXTENSIONS
31 -
32 -# setenv() was introduced in POSIX.1-2008.
33 -# strtok_r() was introduced in POSIX.1-2001.
34 -AC_CHECK_FUNCS([setenv strtok_r])
35 -
36 -# strndup() was introduced in POSIX.1-2008 and is also an implicitly declared built-in function in GCC.
37 -AC_MSG_CHECKING([for strndup])
38 -old_CFLAGS="${CFLAGS}"
39 -CFLAGS="${CFLAGS} -Wall -Werror -Wextra"
40 -AC_LINK_IFELSE([AC_LANG_SOURCE([[#include <string.h>
41 -int main()
42 -{
43 - strndup("", 0);
44 - return 0;
45 -}]])], [have_strndup="1"], [have_strndup="0"])
46 -if test "${have_strndup}" = "1"; then
47 - AC_MSG_RESULT([yes])
48 - AC_DEFINE([HAVE_STRNDUP], [1], [Define to 1 if you have the 'strndup' function.])
49 -else
50 - AC_MSG_RESULT([no])
51 -fi
52 -CFLAGS="${old_CFLAGS}"
53 -
54 # Create output files.
55 -AC_CONFIG_HEADERS([config.h])
56 AC_CONFIG_FILES([Makefile python.eselect])
57
58 AC_OUTPUT
59 diff --git a/python-wrapper.c b/python-wrapper.c
60 deleted file mode 100644
61 index 75a1de4..0000000
62 --- a/python-wrapper.c
63 +++ /dev/null
64 @@ -1,244 +0,0 @@
65 -/* Copyright 1999-2010 Gentoo Foundation
66 - * Distributed under the terms of the GNU General Public License v2
67 - */
68 -
69 -#include "config.h"
70 -
71 -#include <dirent.h>
72 -#include <limits.h>
73 -#include <stdlib.h>
74 -#include <stdio.h>
75 -#include <string.h>
76 -#include <unistd.h>
77 -#include <sys/stat.h>
78 -
79 -#ifndef ENVD
80 -#define ENVD "/etc/env.d"
81 -#endif
82 -
83 -#define ENVD_CONFIG ENVD "/python/config"
84 -
85 -/* 127 is the standard return code for "command not found" */
86 -#define EXIT_ERROR 127
87 -
88 -char* dir_cat(const char* dir, const char* file)
89 -{
90 - size_t dir_len = strlen(dir);
91 - char* abs = malloc(dir_len + strlen(file) + 2);
92 - strcpy(abs, dir);
93 - abs[dir_len] = '/';
94 - abs[dir_len + 1] = 0;
95 - return strcat(abs, file);
96 -}
97 -
98 -const char* find_path(const char* exe)
99 -{
100 - const char* last_slash = strrchr(exe, '/');
101 - if (last_slash)
102 - {
103 -#ifdef HAVE_STRNDUP
104 - return strndup(exe, last_slash - exe);
105 -#else
106 - size_t len = last_slash - exe;
107 - char* ret = malloc(sizeof(char) * (len + 1));
108 - memcpy(ret, exe, len);
109 - ret[len] = '\0';
110 - return(ret);
111 -#endif
112 - }
113 - const char* PATH = getenv("PATH");
114 - if (! PATH)
115 - {
116 - /* If PATH is unset, then it defaults to ":/bin:/usr/bin", per
117 - * execvp(3).
118 - */
119 - PATH = ":/bin:/usr/bin";
120 - }
121 - char* path = strdup(PATH);
122 -#ifdef HAVE_STRTOK_R
123 - char* state = NULL;
124 - const char* token = strtok_r(path, ":", &state);
125 -#else
126 - const char* token = strtok(path, ":");
127 -#endif
128 - while (token)
129 - {
130 - /* If an element of PATH is empty ("::"), then it is "." */
131 - if (! *token)
132 - {
133 - token = ".";
134 - }
135 - struct stat sbuf;
136 - char* str = dir_cat(token, exe);
137 - if (stat(str, &sbuf) == 0 && (S_ISREG(sbuf.st_mode) || S_ISLNK(sbuf.st_mode)))
138 - {
139 - return token;
140 - }
141 -#ifdef HAVE_STRTOK_R
142 - token = strtok_r(NULL, ":", &state);
143 -#else
144 - token = strtok(NULL, ":");
145 -#endif
146 - }
147 - return NULL;
148 -}
149 -
150 -/* True if a valid file name, and not "python" */
151 -int valid_interpreter(const char* name)
152 -{
153 - if (! name || ! *name || (strcmp(name, "python") == 0))
154 - {
155 - return 0;
156 - }
157 - return 1;
158 -}
159 -
160 -int get_version(const char* name)
161 -{
162 - /* Only find files beginning with "python" - this is a fallback,
163 - * so we only want CPython
164 - */
165 - if (! valid_interpreter(name) || strncmp(name, "python", 6) != 0)
166 - return -1;
167 - int pos = 6;
168 - int major = 0;
169 - int minor = 0;
170 - if (name[pos] < '0' || name[pos] > '9')
171 - return -1;
172 - do
173 - {
174 - major = major * 10 + name[pos] - '0';
175 - if (! name[++pos])
176 - return -1;
177 - }
178 - while (name[pos] >= '0' && name[pos] <= '9');
179 - if (name[pos++] != '.')
180 - return -1;
181 - if (name[pos] < '0' || name[pos] > '9')
182 - return -1;
183 - do
184 - {
185 - minor = minor * 10 + name[pos] - '0';
186 - if (! name[++pos])
187 - return (major << 8) | minor;
188 - }
189 - while (name[pos] >= '0' && name[pos] <= '9');
190 - return -1;
191 -}
192 -
193 -int filter_python(const struct dirent* file)
194 -{
195 - return get_version(file->d_name) != -1;
196 -}
197 -
198 -/* This implements a version sort, such that the following order applies:
199 - * <invalid file names> (should never be seen)
200 - * python2.6
201 - * python2.9
202 - * python2.10
203 - * python3.0
204 - * python3.1
205 - * python3.2
206 - * python9.1
207 - * python9.9
208 - * python9.10
209 - * python10.1
210 - * python10.9
211 - * python10.10
212 - */
213 -int sort_python(const struct dirent**f1, const struct dirent** f2)
214 -{
215 - int ver1 = get_version((*f1)->d_name);
216 - int ver2 = get_version((*f2)->d_name);
217 - return ver1 - ver2;
218 -}
219 -
220 -const char* find_latest(const char* exe)
221 -{
222 - const char* path = find_path(exe);
223 - if (! path || ! *path)
224 - {
225 - path = "/usr/bin";
226 - }
227 - struct dirent** namelist;
228 - int n = scandir(path, &namelist, filter_python, sort_python);
229 - const char* ret = NULL;
230 - if (n < 0)
231 - {
232 - return NULL;
233 - }
234 - /* Walk backwards through the list. */
235 - while (n--)
236 - {
237 - if (! ret)
238 - ret = strdup(namelist[n]->d_name);
239 - free(namelist[n]);
240 - }
241 - free(namelist);
242 - return ret;
243 -}
244 -
245 -int main(int argc, char** argv)
246 -{
247 - const char* EPYTHON = getenv("EPYTHON");
248 - int script_name_index = -1;
249 - if (! valid_interpreter(EPYTHON))
250 - {
251 - FILE* f = fopen(ENVD_CONFIG, "r");
252 - if (f)
253 - {
254 - struct stat st;
255 - fstat(fileno(f), &st);
256 - size_t size = st.st_size;
257 - char* cont = malloc(size + 1);
258 - cont = fgets(cont, size + 1, f);
259 - fclose(f);
260 - size_t len = strlen(cont);
261 - if (len && cont[len - 1] == '\n')
262 - cont[len - 1] = 0;
263 - EPYTHON = cont;
264 - }
265 - }
266 -
267 - if (! valid_interpreter(EPYTHON))
268 - EPYTHON = find_latest(argv[0]);
269 -
270 - if (! EPYTHON)
271 - return EXIT_ERROR;
272 -
273 - if (strchr(EPYTHON, '/'))
274 - {
275 - fprintf(stderr, "Invalid value of EPYTHON variable or invalid configuration of Python wrapper\n");
276 - return EXIT_ERROR;
277 - }
278 -
279 - /* Set GENTOO_PYTHON_PROCESS_NAME environmental variable, if a script with a Python shebang is probably being executed.
280 - * argv[0] can be "python", when "#!/usr/bin/env python" shebang is used. */
281 - if (argc >= 2 && (argv[0][0] == '/' || strcmp(argv[0], "python") == 0) && (argv[1][0] == '/' || strncmp(argv[1], "./", 2) == 0))
282 - script_name_index = 1;
283 - else if (argc >= 3 && argv[0][0] == '/' && argv[1][0] == '-' && (argv[2][0] == '/' || strncmp(argv[2], "./", 2) == 0))
284 - script_name_index = 2;
285 - if (script_name_index > 0)
286 - {
287 - char* script_name = strrchr(argv[script_name_index], '/') + 1;
288 -#ifdef HAVE_SETENV
289 - setenv("GENTOO_PYTHON_PROCESS_NAME", script_name, 1);
290 -#else
291 - char* script_name_variable = malloc(sizeof(char) * (strlen("GENTOO_PYTHON_PROCESS_NAME=") + strlen(script_name)));
292 - sprintf(script_name_variable, "GENTOO_PYTHON_PROCESS_NAME=%s", script_name);
293 - putenv(script_name_variable);
294 -#endif
295 - }
296 -
297 - const char* path = find_path(argv[0]);
298 - if (path)
299 - {
300 - argv[0] = dir_cat(path, EPYTHON);
301 - execv(argv[0], argv);
302 - /* If this failed, then just search the PATH. */
303 - }
304 -
305 - argv[0] = (char*) EPYTHON;
306 - execvp(EPYTHON, argv);
307 - return EXIT_ERROR;
308 -}
309 --
310 2.6.3