symbian-qemu-0.9.1-12/python-2.6.1/PCbuild/kill_python.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 */