~pythonregexp2.7/python/issue2636-01+09-01-01

« back to all changes in this revision

Viewing changes to PC/VS8.0/kill_python.c

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-09-22 00:02:12 UTC
  • mfrom: (39022.1.34 Regexp-2.7)
  • Revision ID: darklord@timehorse.com-20080922000212-7r0q4f4ugiq57jph
Merged in changes from the Atomic Grouping / Possessive Qualifiers branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Helper program for killing lingering python[_d].exe processes before
 
3
 * building, thus attempting to avoid build failures due to files being
 
4
 * locked.
 
5
 */
 
6
 
 
7
#include <windows.h>
 
8
#include <wchar.h>
 
9
#include <tlhelp32.h>
 
10
#include <stdio.h>
 
11
 
 
12
#pragma comment(lib, "psapi")
 
13
 
 
14
#ifdef _DEBUG
 
15
#define PYTHON_EXE          (L"python_d.exe")
 
16
#define PYTHON_EXE_LEN      (12)
 
17
#define KILL_PYTHON_EXE     (L"kill_python_d.exe")
 
18
#define KILL_PYTHON_EXE_LEN (17)
 
19
#else
 
20
#define PYTHON_EXE          (L"python.exe")
 
21
#define PYTHON_EXE_LEN      (10)
 
22
#define KILL_PYTHON_EXE     (L"kill_python.exe")
 
23
#define KILL_PYTHON_EXE_LEN (15)
 
24
#endif
 
25
 
 
26
int
 
27
main(int argc, char **argv)
 
28
{
 
29
    HANDLE   hp, hsp, hsm; /* process, snapshot processes, snapshot modules */
 
30
    DWORD    dac, our_pid;
 
31
    size_t   len;
 
32
    wchar_t  path[MAX_PATH+1];
 
33
 
 
34
    MODULEENTRY32W  me;
 
35
    PROCESSENTRY32W pe;
 
36
 
 
37
    me.dwSize = sizeof(MODULEENTRY32W);
 
38
    pe.dwSize = sizeof(PROCESSENTRY32W);
 
39
 
 
40
    memset(path, 0, MAX_PATH+1);
 
41
 
 
42
    our_pid = GetCurrentProcessId();
 
43
 
 
44
    hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid);
 
45
    if (hsm == INVALID_HANDLE_VALUE) {
 
46
        printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError());
 
47
        return 1;
 
48
    }
 
49
 
 
50
    if (!Module32FirstW(hsm, &me)) {
 
51
        printf("Module32FirstW[1] failed: %d\n", GetLastError());
 
52
        CloseHandle(hsm);
 
53
        return 1;
 
54
    }
 
55
 
 
56
    /*
 
57
     * Enumerate over the modules for the current process in order to find
 
58
     * kill_process[_d].exe, then take a note of the directory it lives in.
 
59
     */
 
60
    do {
 
61
        if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN))
 
62
            continue;
 
63
 
 
64
        len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN;
 
65
        wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); 
 
66
 
 
67
        break;
 
68
 
 
69
    } while (Module32NextW(hsm, &me));
 
70
 
 
71
    CloseHandle(hsm);
 
72
 
 
73
    if (path == NULL) {
 
74
        printf("failed to discern directory of running process\n");
 
75
        return 1;
 
76
    }
 
77
 
 
78
    /*
 
79
     * Take a snapshot of system processes.  Enumerate over the snapshot,
 
80
     * looking for python processes.  When we find one, verify it lives
 
81
     * in the same directory we live in.  If it does, kill it.  If we're
 
82
     * unable to kill it, treat this as a fatal error and return 1.
 
83
     * 
 
84
     * The rationale behind this is that we're called at the start of the 
 
85
     * build process on the basis that we'll take care of killing any
 
86
     * running instances, such that the build won't encounter permission
 
87
     * denied errors during linking. If we can't kill one of the processes,
 
88
     * we can't provide this assurance, and the build shouldn't start.
 
89
     */
 
90
 
 
91
    hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
92
    if (hsp == INVALID_HANDLE_VALUE) {
 
93
        printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError());
 
94
        return 1;
 
95
    }
 
96
 
 
97
    if (!Process32FirstW(hsp, &pe)) {
 
98
        printf("Process32FirstW failed: %d\n", GetLastError());
 
99
        CloseHandle(hsp);
 
100
        return 1;
 
101
    }
 
102
 
 
103
    dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE;
 
104
    do {
 
105
 
 
106
        /*
 
107
         * XXX TODO: if we really wanted to be fancy, we could check the 
 
108
         * modules for all processes (not just the python[_d].exe ones)
 
109
         * and see if any of our DLLs are loaded (i.e. python30[_d].dll),
 
110
         * as that would also inhibit our ability to rebuild the solution.
 
111
         * Not worth loosing sleep over though; for now, a simple check 
 
112
         * for just the python executable should be sufficient.
 
113
         */
 
114
 
 
115
        if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN))
 
116
            /* This isn't a python process. */
 
117
            continue;
 
118
 
 
119
        /* It's a python process, so figure out which directory it's in... */
 
120
        hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
 
121
        if (hsm == INVALID_HANDLE_VALUE)
 
122
            /* 
 
123
             * If our module snapshot fails (which will happen if we don't own
 
124
             * the process), just ignore it and continue.  (It seems different
 
125
             * versions of Windows return different values for GetLastError()
 
126
             * in this situation; it's easier to just ignore it and move on vs.
 
127
             * stopping the build for what could be a false positive.)
 
128
             */
 
129
             continue;
 
130
 
 
131
        if (!Module32FirstW(hsm, &me)) {
 
132
            printf("Module32FirstW[2] failed: %d\n", GetLastError());
 
133
            CloseHandle(hsp);
 
134
            CloseHandle(hsm);
 
135
            return 1;
 
136
        }
 
137
 
 
138
        do {
 
139
            if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN))
 
140
                /* Wrong module, we're looking for python[_d].exe... */
 
141
                continue;
 
142
 
 
143
            if (_wcsnicmp(path, me.szExePath, len))
 
144
                /* Process doesn't live in our directory. */
 
145
                break;
 
146
 
 
147
            /* Python process residing in the right directory, kill it!  */
 
148
            hp = OpenProcess(dac, FALSE, pe.th32ProcessID);
 
149
            if (!hp) {
 
150
                printf("OpenProcess failed: %d\n", GetLastError());
 
151
                CloseHandle(hsp);
 
152
                CloseHandle(hsm);
 
153
                return 1;
 
154
            }
 
155
 
 
156
            if (!TerminateProcess(hp, 1)) {
 
157
                printf("TerminateProcess failed: %d\n", GetLastError());
 
158
                CloseHandle(hsp);
 
159
                CloseHandle(hsm);
 
160
                CloseHandle(hp);
 
161
                return 1;
 
162
            }
 
163
 
 
164
            CloseHandle(hp);
 
165
            break;
 
166
 
 
167
        } while (Module32NextW(hsm, &me));
 
168
 
 
169
        CloseHandle(hsm);
 
170
 
 
171
    } while (Process32NextW(hsp, &pe));
 
172
 
 
173
    CloseHandle(hsp);
 
174
 
 
175
    return 0;
 
176
}
 
177
 
 
178
/* vi: set ts=8 sw=4 sts=4 expandtab */