dirmngr: Implement timeout for dirmngr_ldap under Windows.
authorWerner Koch <wk@gnupg.org>
Wed, 2 May 2018 16:40:01 +0000 (18:40 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 2 May 2018 16:40:01 +0000 (18:40 +0200)
* dirmngr/dirmngr_ldap.c (alarm_thread) [W32]: New.
(set_timeout): Implement for W32.
--

GnuPG-bug-id: 3937
Signed-off-by: Werner Koch <wk@gnupg.org>
dirmngr/dirmngr_ldap.c

index e05c779..8452c3b 100644 (file)
@@ -381,16 +381,56 @@ catch_alarm (int dummy)
 }
 #endif
 
+
+#ifdef HAVE_W32_SYSTEM
+static DWORD CALLBACK
+alarm_thread (void *arg)
+{
+  HANDLE timer = arg;
+
+  WaitForSingleObject (timer, INFINITE);
+  _exit (10);
+
+  return 0;
+}
+#endif
+
+
 static void
 set_timeout (my_opt_t myopt)
 {
+  if (myopt->alarm_timeout)
+    {
 #ifdef HAVE_W32_SYSTEM
-  /* FIXME for W32.  */
-  (void)myopt;
+      static HANDLE timer;
+      LARGE_INTEGER due_time;
+
+      /* A negative value is a relative time.  */
+      due_time.QuadPart = (unsigned long long)-10000000 * myopt->alarm_timeout;
+
+      if (!timer)
+        {
+          SECURITY_ATTRIBUTES sec_attr;
+          DWORD tid;
+
+          memset (&sec_attr, 0, sizeof sec_attr);
+          sec_attr.nLength = sizeof sec_attr;
+          sec_attr.bInheritHandle = FALSE;
+
+          /* Create a manual resetable timer.  */
+          timer = CreateWaitableTimer (NULL, TRUE, NULL);
+          /* Intially set the timer.  */
+          SetWaitableTimer (timer, &due_time, 0, NULL, NULL, 0);
+
+          if (CreateThread (&sec_attr, 0, alarm_thread, timer, 0, &tid))
+            log_error ("failed to create alarm thread\n");
+        }
+      else /* Retrigger the timer.  */
+        SetWaitableTimer (timer, &due_time, 0, NULL, NULL, 0);
 #else
-  if (myopt->alarm_timeout)
-    alarm (myopt->alarm_timeout);
+      alarm (myopt->alarm_timeout);
 #endif
+    }
 }