diff options
author | Andre Heinecke <aheinecke@gnupg.org> | 2019-04-29 08:54:39 +0200 |
---|---|---|
committer | Andre Heinecke <aheinecke@gnupg.org> | 2019-04-29 08:54:39 +0200 |
commit | 03df28b18b92b3fd3d2ba1000903c088dc5b0fcf (patch) | |
tree | debb1eebab5e00589231aa4eb2d2d4e8ce9f4c9c /common | |
parent | scd: Add new command: KEYINFO. (diff) | |
download | gnupg2-03df28b18b92b3fd3d2ba1000903c088dc5b0fcf.tar.xz gnupg2-03df28b18b92b3fd3d2ba1000903c088dc5b0fcf.zip |
common,w32: Breakaway detached childs when in job
* common/exechelp-w32.c (gnupg_spawn_process_detached): Add
CREATE_BREAKAWAY_FROM_JOB creation flag if required.
--
When the gpg process is assigned to a W32 "Job" the
child processes are killed once the Job is finished.
As we want our detached processes to linger e.g.
gpg-agent the breakaway flag is required in
that case.
GnuPG-Bug-Id: T4333
Thanks to Jan Echternach for reporting this and providing
a patch.
Signed-off-by: Andre Heinecke <aheinecke@gnupg.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/exechelp-w32.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index 86b1d6869..ea158a33f 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -856,6 +856,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], STARTUPINFO si; int cr_flags; char *cmdline; + BOOL in_job = FALSE; /* We don't use ENVP. */ @@ -884,6 +885,50 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[], | GetPriorityClass (GetCurrentProcess ()) | CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS); + + /* Check if we were spawned as part of a Job. + * In a job we need to add CREATE_BREAKAWAY_FROM_JOB + * to the cr_flags, otherwise our child processes + * are killed when we terminate. */ + if (!IsProcessInJob (GetCurrentProcess(), NULL, &in_job)) + { + log_error ("IsProcessInJob() failed: %s\n", w32_strerror (-1)); + in_job = FALSE; + } + + if (in_job) + { + /* Only try to break away from job if it is allowed, otherwise + * CreateProcess() would fail with an "Access is denied" error. */ + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + if (!QueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, + &info, sizeof info, NULL)) + { + log_error ("QueryInformationJobObject() failed: %s\n", + w32_strerror (-1)); + } + else if ((info.BasicLimitInformation.LimitFlags & + JOB_OBJECT_LIMIT_BREAKAWAY_OK)) + { + log_debug ("Using CREATE_BREAKAWAY_FROM_JOB flag\n"); + cr_flags |= CREATE_BREAKAWAY_FROM_JOB; + } + else if ((info.BasicLimitInformation.LimitFlags & + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)) + { + /* The child process should automatically detach from the job. */ + log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag; " + "JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set\n"); + } + else + { + /* It seems that the child process must remain in the job. + * This is not necessarily an error, although it can cause premature + * termination of the child process when the job is closed. */ + log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag\n"); + } + } + /* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */ /* pgmname, cmdline); */ if (!CreateProcess (pgmname, /* Program to start. */ |