summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorAndre Heinecke <aheinecke@gnupg.org>2019-04-29 08:54:39 +0200
committerAndre Heinecke <aheinecke@gnupg.org>2019-04-29 08:54:39 +0200
commit03df28b18b92b3fd3d2ba1000903c088dc5b0fcf (patch)
treedebb1eebab5e00589231aa4eb2d2d4e8ce9f4c9c /common
parentscd: Add new command: KEYINFO. (diff)
downloadgnupg2-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.c45
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. */