From 007dde93cc3971cb51d08e8c082e172506ae7f80 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 2 May 2018 18:40:01 +0200 Subject: [PATCH] dirmngr: Implement timeout for dirmngr_ldap under Windows. * dirmngr/dirmngr_ldap.c (alarm_thread) [W32]: New. (set_timeout): Implement for W32. -- GnuPG-bug-id: 3937 Signed-off-by: Werner Koch --- dirmngr/dirmngr_ldap.c | 50 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/dirmngr/dirmngr_ldap.c b/dirmngr/dirmngr_ldap.c index e05c77925..8452c3ba0 100644 --- a/dirmngr/dirmngr_ldap.c +++ b/dirmngr/dirmngr_ldap.c @@ -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) { -#ifdef HAVE_W32_SYSTEM - /* FIXME for W32. */ - (void)myopt; -#else if (myopt->alarm_timeout) - alarm (myopt->alarm_timeout); + { +#ifdef HAVE_W32_SYSTEM + 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 + alarm (myopt->alarm_timeout); #endif + } }