[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-windows
Subject:    [patch] more advanced implementation of kill()
From:       Jarosław Staniek <js () iidea ! pl>
Date:       2008-02-14 1:32:54
Message-ID: 47B39A46.3010901 () iidea ! pl
[Download RAW message or body]

For review;

We're supporting most more useful signals now, also signal 0 which is used for 
checking for existence of a process - we can now expect ESRCH result when 
there is no process for a given PID.
This is good for and various other unique processes, e.g. for KMail which will 
no longer display confusing "KMail already seems to be running on another 
display on this machine." message.

-- 
regards / pozdrawiam, Jaroslaw Staniek
  Sponsored by OpenOffice Polska (http://www.openoffice.com.pl/en) to work on
  Kexi & KOffice (http://www.kexi.pl/en, http://www.koffice.org/kexi)
  KDE Libraries for MS Windows (http://windows.kde.org)

["kill.patch" (text/plain)]

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)


_______________________________________________
Kde-windows mailing list
Kde-windows@kde.org
https://mail.kde.org/mailman/listinfo/kde-windows


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic