Below is the list of changes that have just been committed into a local
5.1 repository of iggy. When iggy does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-01-22 19:34:55-05:00, iggy@alf.(none) +3 -0
WL#4072 Move mysql_kill from Connector /MJX to the Server
- Move the code for mysql_kill to Server.
extra/CMakeLists.txt@stripped, 2008-01-22 19:34:50-05:00, iggy@alf.(none) +4 -0
WL#4072 Move mysql_kill from Connector /MJX to the Server
- Add project.
extra/Makefile.am@stripped, 2008-01-22 19:34:50-05:00, iggy@alf.(none) +1 -1
WL#4072 Move mysql_kill from Connector /MJX to the Server
- Add to src dist.
extra/mysql_kill.cpp@stripped, 2008-01-22 19:34:50-05:00, iggy@alf.(none) +244 -0
WL#4072 Move mysql_kill from Connector /MJX to the Server
- New client utility.
extra/mysql_kill.cpp@stripped, 2008-01-22 19:34:50-05:00, iggy@alf.(none) +0 -0
diff -Nrup a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2007-12-27 19:07:38 -05:00
+++ b/extra/CMakeLists.txt 2008-01-22 19:34:50 -05:00
@@ -50,6 +50,10 @@ TARGET_LINK_LIBRARIES(resolveip strings
ADD_EXECUTABLE(replace replace.c)
TARGET_LINK_LIBRARIES(replace strings mysys debug dbug wsock32)
+ADD_EXECUTABLE(mysql_kill mysql_kill.cpp)
+TARGET_LINK_LIBRARIES(mysql_kill debug dbug wsock32)
+
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("myTest" "asInvoker")
+ MYSQL_EMBED_MANIFEST("mysql_kill" "asInvoker")
ENDIF(EMBED_MANIFESTS)
diff -Nrup a/extra/Makefile.am b/extra/Makefile.am
--- a/extra/Makefile.am 2007-08-30 19:23:48 -04:00
+++ b/extra/Makefile.am 2008-01-22 19:34:50 -05:00
@@ -46,7 +46,7 @@ bin_PROGRAMS = replace perror resolveip
resolve_stack_dump mysql_waitpid innochecksum
noinst_PROGRAMS = charset2html
EXTRA_PROGRAMS = comp_err
-EXTRA_DIST = CMakeLists.txt
+EXTRA_DIST = CMakeLists.txt mysql_kill.cpp
perror.o: perror.c
$(COMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $<
diff -Nrup a/extra/mysql_kill.cpp b/extra/mysql_kill.cpp
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/extra/mysql_kill.cpp 2008-01-22 19:34:50 -05:00
@@ -0,0 +1,244 @@
+/*
+ Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+// mysql_kill.cpp : a variation on the unix "kill" for use with mysqld on windows
+// Author: Eric Herman
+// Adapted from original "kill.cpp" by Eric Herman and Kendrick Shaw.
+// SafeTerminateProcess Adaptded by code written by Reggie Burnett.
+
+// SIGHUP is replaced by OpenEvent(EVENT_MODIFY_STATE, FALSE, "MySQLShutdown<PID>");
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include <stdio.h>
+#include <iostream>
+#include <process.h>
+#include <windows.h>
+#include <windef.h>
+#include <process.h>
+
+typedef BOOL (*process_func)(HANDLE hProcess, UINT uExitCode);
+
+// ------------------------------------
+
+BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
+{
+ DWORD dwTID, dwCode, dwErr = 0;
+ HANDLE hProcessDup = INVALID_HANDLE_VALUE;
+ HANDLE hRT = NULL;
+ HINSTANCE hKernel = GetModuleHandle("Kernel32");
+ BOOL bSuccess = FALSE;
+
+ // warning C4312: 'type cast' :
+ // conversion from 'UINT' to 'PVOID' of greater size
+ // FIXME: Since our usage is always ZERO maybe we don't care,
+ // but still it would be nice to have a clean compile that deals
+ // with this warning the "right" way.
+ PVOID pvExitCode = (PVOID)uExitCode;
+
+ BOOL bDup = DuplicateHandle(GetCurrentProcess(),
+ hProcess,
+ GetCurrentProcess(),
+ &hProcessDup,
+ PROCESS_ALL_ACCESS,
+ FALSE,
+ 0);
+
+ // Detect the special case where the process is
+ // already dead...
+ if ( GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode)
+ && (dwCode == STILL_ACTIVE) )
+ {
+ FARPROC pfnExitProc;
+
+ pfnExitProc = GetProcAddress(hKernel, "ExitProcess");
+
+ hRT = CreateRemoteThread((bDup) ? hProcessDup : hProcess,
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)pfnExitProc,
+ pvExitCode,
+ 0,
+ &dwTID);
+
+ if ( hRT == NULL )
+ {
+ dwErr = GetLastError();
+ }
+ }
+ else
+ {
+ dwErr = ERROR_PROCESS_ABORTED;
+ }
+
+ if ( hRT )
+ {
+ // Must wait (miliseconds) for process to terminate to
+ // guarantee that it has exited...
+ WaitForSingleObject((bDup) ? hProcessDup : hProcess, 20 * 1000);
+ // WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
+
+ CloseHandle(hRT);
+ bSuccess = TRUE;
+ }
+
+ if ( bDup )
+ {
+ CloseHandle(hProcessDup);
+ }
+
+ if ( !bSuccess )
+ {
+ SetLastError(dwErr);
+ }
+ return bSuccess;
+}
+
+// ------------------------------------
+
+// return 0 on success or error code
+int ApplyToProcess(DWORD dwDesiredAccess, DWORD process_id, process_func pfunc)
+{
+ UINT uExitCode = 0;
+
+ HANDLE h_process = OpenProcess(dwDesiredAccess, FALSE, process_id);
+
+ if (h_process == NULL)
+ {
+ return GetLastError();
+ }
+
+ BOOL return_val= pfunc(h_process, uExitCode);
+
+ CloseHandle(h_process);
+
+ return return_val ? (int) uExitCode : GetLastError();
+}
+
+// return 0 on success or error code
+int OpenAndSetEvent(DWORD dwDesiredAccess, const char* eventName)
+{
+ HANDLE hEvent= OpenEvent(dwDesiredAccess, FALSE, eventName);
+ if (hEvent == NULL)
+ {
+ fprintf(stderr, "No HANDLE %s", eventName);
+ // fprintf(stderr, "\nLast Error: %d", GetLastError());
+ return GetLastError();
+ }
+ SetEvent(hEvent);
+ CloseHandle(hEvent);
+ return 0;
+}
+
+// return 0 on success or error code
+int Terminate(DWORD pid)
+{
+ // fprint(stderr, "SafeTerminateProcess %d", pid);
+ int safe = ApplyToProcess(PROCESS_TERMINATE, pid, &SafeTerminateProcess);
+ if( safe == 0 )
+ {
+ return 0;
+ }
+ fprintf(stderr, "TerminateProcess %d", pid);
+ return ApplyToProcess(PROCESS_TERMINATE, pid, (process_func)&TerminateProcess);
+}
+
+BOOL KnownProcessInner(HANDLE h_process, UINT uExitCode)
+{
+ // already returned if process doesn't exist
+ return TRUE;
+}
+
+// return 0 on success or error code
+int KnownProcess(DWORD dwDesiredAccess, DWORD pid)
+{
+ return ApplyToProcess(dwDesiredAccess, pid, &KnownProcessInner);
+}
+
+// return 0 on success or error code
+int KnownProcess(DWORD pid)
+{
+ return KnownProcess(PROCESS_TERMINATE, pid);
+}
+
+
+// ------------------------------------
+
+
+void Usage(const char *argv0)
+{
+ char usage[2048];
+ sprintf_s(usage, 2048, "USAGE: %s [-0 -9] PID", argv0);
+ printf(usage);
+}
+
+int SetEventMySQLShutdown(DWORD pid)
+{
+ // If shutdown_event_name as defined mysqld.cc changes
+ // from in "MySQLShutdown<PID>" we must change this also.
+ // Perhaps the name should be moved to a constant and
+ // in a header file that we could include here, too?
+ char buff[60];
+ sprintf_s(buff, 60, "MySQLShutdown%d", pid);
+ return OpenAndSetEvent(EVENT_MODIFY_STATE, buff);
+}
+
+int main(int argc, const char** argv)
+{
+ DWORD pid = 0;
+
+ if ((argc == 2) && (sscanf_s(argv[1], "%30u", &pid) == 1))
+ {
+ return SetEventMySQLShutdown(pid);
+ }
+
+
+ // 0 == NULL (process exists)
+ // 1 == HUP (hang up)
+ // 2 == INT (interrupt)
+ // 3 == QUIT (quit)
+ // 6 == ABRT (abort)
+ // 9 == KILL (non-catchable, non-ignorable kill)
+ // 14 == ALRM (alarm clock)
+ // 15 == TERM (software termination signal)
+
+ if ((argc == 3) && (sscanf_s(argv[2], "%30u", &pid) == 1))
+ {
+ if (strcmp(argv[1], "-0")==0)
+ {
+ // 0 == NUL (process exists)
+ return KnownProcess(pid);
+ }
+
+ if (strcmp(argv[1], "-9")==0)
+ {
+ // 9 == KILL (non-catchable, non-ignorable kill)
+ return Terminate(pid);
+ }
+
+ // We could elect to treat ALL other signals as nice shutdown
+ // (perhaps excluding 14 (ALRM)) and not just HUP and QUIT.
+ if ((strcmp(argv[1], "-1")==0) || (strcmp(argv[1], "-3")==0))
+ {
+ return SetEventMySQLShutdown(pid);
+ }
+ }
+
+ Usage(argv[0]);
+ return 1;
+}