annotate mercurial/exewrapper.c @ 17583:55724f42fa14

merge with stable
author Matt Mackall <mpm@selenic.com>
date Mon, 17 Sep 2012 15:13:17 -0500
parents 3fbc6e3abdbd
children 93d97a212559
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17058
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
1 /*
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
2 exewrapper.c - wrapper for calling a python script on Windows
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
3
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
4 Copyright 2012 Adrian Buehlmann <adrian@cadifra.com> and others
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
5
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
6 This software may be used and distributed according to the terms of the
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
7 GNU General Public License version 2 or any later version.
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
8 */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
9
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
10 #include <Python.h>
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
11 #include <windows.h>
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
12
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
13
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
14 #ifdef __GNUC__
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
15 int strcat_s(char *d, size_t n, const char *s)
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
16 {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
17 return !strncat(d, s, n);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
18 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
19 #endif
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
20
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
21
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
22 static char pyscript[MAX_PATH + 10];
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
23
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
24 int main(int argc, char *argv[])
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
25 {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
26 char *dot;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
27 int ret;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
28 int i;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
29 int n;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
30 char **pyargv;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
31 WIN32_FIND_DATA fdata;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
32 HANDLE hfind;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
33 const char *err;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
34
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
35 if (GetModuleFileName(NULL, pyscript, sizeof(pyscript)) == 0)
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
36 {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
37 err = "GetModuleFileName failed";
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
38 goto bail;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
39 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
40
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
41 dot = strrchr(pyscript, '.');
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
42 if (dot == NULL) {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
43 err = "malformed module filename";
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
44 goto bail;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
45 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
46 *dot = 0; /* cut trailing ".exe" */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
47
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
48 hfind = FindFirstFile(pyscript, &fdata);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
49 if (hfind != INVALID_HANDLE_VALUE) {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
50 /* pyscript exists, close handle */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
51 FindClose(hfind);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
52 } else {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
53 /* file pyscript isn't there, take <pyscript>exe.py */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
54 strcat_s(pyscript, sizeof(pyscript), "exe.py");
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
55 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
56
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
57 /*
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
58 Only add the pyscript to the args, if it's not already there. It may
17063
3fbc6e3abdbd exewrapper: use generic term script
Adrian Buehlmann <adrian@cadifra.com>
parents: 17058
diff changeset
59 already be there, if the script spawned a child process of itself, in
17058
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
60 the same way as it got called, that is, with the pyscript already in
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
61 place. So we optionally accept the pyscript as the first argument
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
62 (argv[1]), letting our exe taking the role of the python interpreter.
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
63 */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
64 if (argc >= 2 && strcmp(argv[1], pyscript) == 0) {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
65 /*
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
66 pyscript is already in the args, so there is no need to copy
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
67 the args and we can directly call the python interpreter with
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
68 the original args.
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
69 */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
70 return Py_Main(argc, argv);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
71 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
72
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
73 /*
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
74 Start assembling the args for the Python interpreter call. We put the
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
75 name of our exe (argv[0]) in the position where the python.exe
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
76 canonically is, and insert the pyscript next.
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
77 */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
78 pyargv = malloc((argc + 5) * sizeof(char*));
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
79 if (pyargv == NULL) {
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
80 err = "not enough memory";
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
81 goto bail;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
82 }
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
83 n = 0;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
84 pyargv[n++] = argv[0];
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
85 pyargv[n++] = pyscript;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
86
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
87 /* copy remaining args from the command line */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
88 for (i = 1; i < argc; i++)
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
89 pyargv[n++] = argv[i];
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
90 /* argv[argc] is guaranteed to be NULL, so we forward that guarantee */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
91 pyargv[n] = NULL;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
92
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
93 ret = Py_Main(n, pyargv); /* The Python interpreter call */
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
94
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
95 free(pyargv);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
96 return ret;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
97
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
98 bail:
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
99 fprintf(stderr, "abort: %s\n", err);
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
100 return 255;
d5422faf648c exewrapper: adding new exewrapper.c
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
101 }