Index: kdewin32/src/signal.c
===================================================================
--- kdewin32/src/signal.c	(revision 772505)
+++ kdewin32/src/signal.c	(working copy)
@@ -24,23 +24,63 @@
 #include <errno.h>
 #include <signal.h>
 
+/* used in kill() */
+int handle_kill_result(HANDLE h)
+{
+  if (GetLastError() == ERROR_ACCESS_DENIED)
+    errno = EPERM;
+  else if (GetLastError() == ERROR_NO_MORE_FILES)
+    errno = ESRCH;
+  else
+    errno = EINVAL;
+  CloseHandle(h);
+  return -1;
+}
+
 KDEWIN32_EXPORT int kill(pid_t pid, int sig)
 {
   HANDLE h;
-  if( sig != 0 && sig != EINVAL || pid == 0 ) {
+  HANDLE h_thread;
+  DWORD thread_id;
+  if (pid <= 0 || sig < 0) {
     errno = EINVAL;
     return -1;
   }
-  h = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD)pid);
-  if( h ) {
-    if( sig == SIGKILL ) {
-      TerminateProcess(h, sig);
-    }
+  h = OpenProcess(
+    sig == 0 ? PROCESS_QUERY_INFORMATION|PROCESS_VM_READ : PROCESS_ALL_ACCESS, 
+    FALSE, (DWORD)pid);
+  if (!h) {
     CloseHandle(h);
-    return 0;
+    errno = ESRCH;
+    return -1;
   }
-  errno = ESRCH;
-  return -1;
+  switch (sig) {
+  case 0:
+    break; /* we just wanted to know if the process exists  */
+  case SIGINT:
+    if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid))
+      return handle_kill_result(h);
+    break;
+  case SIGQUIT:
+    if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, (DWORD)pid))
+      return handle_kill_result(h);
+    break;
+  case SIGKILL:
+    if (!TerminateProcess(h, sig))
+      return handle_kill_result(h);
+    break;
+  default:
+    h_thread = CreateRemoteThread(
+      h, NULL, 0,
+      (LPTHREAD_START_ROUTINE)(GetProcAddress(GetModuleHandleA("KERNEL32.DLL"), "ExitProcess")),
+      0, 0, &thread_id);
+    if (h_thread)
+      WaitForSingleObject(h_thread, 5);
+    else
+      return handle_kill_result(h);
+  }
+  CloseHandle(h);
+  return 0;
 }
 
 KDEWIN32_EXPORT pid_t waitpid(pid_t p, int *a, int b)