Improved W32 SetForegroundWindow hacks.

This commit is contained in:
Werner Koch 2009-06-12 16:58:45 +00:00
parent f4e35be325
commit 148f51bb3e
16 changed files with 171 additions and 49 deletions

View File

@ -1,3 +1,26 @@
2009-06-12 Werner Koch <wk@g10code.com>
* gpgme-w32spawn.c (translate_get_from_file): Parse optional spawn
flags. Add new arg R_FLAGS. Fix segv on file w/o LF.
(translate_handles): Add new arg R_FLAGS. Avoid possible segv.
(main): Pass flags for my_spawn.
(my_spawn): Add arg FLAGS and implement AllowSetForegroundWindow.
* priv-io.h (IOSPAWN_FLAG_ALLOW_SET_FG): New.
* w32-io.c (_gpgme_io_spawn): Add arg FLAGS and implement it.
* w32-glib-io.c (_gpgme_io_spawn): Ditto.
* w32-qt-io.cpp (_gpgme_io_spawn): Ditto.
* posix-io.c (_gpgme_io_spawn): Add dummy arg FLAGS.
* engine-gpg.c (start): Call spawn with new flag.
* w32-util.c (_gpgme_allow_set_foregound_window): Rename to
_gpgme_allow_set_foreground_window. Change all callers.
* posix-util.c (_gpgme_allow_set_foreground_window): Ditto.
2009-06-10 Werner Koch <wk@g10code.com>
* w32-util.c (_gpgme_allow_set_foregound_window): Add trace support.
2009-06-09 Werner Koch <wk@g10code.com> 2009-06-09 Werner Koch <wk@g10code.com>
* engine-gpg.c (gpg_io_event): Test for cmd.fd. * engine-gpg.c (gpg_io_event): Test for cmd.fd.

View File

@ -102,7 +102,7 @@ read_gpgconf_dirs (void)
cfd[0].fd = rp[1]; cfd[0].fd = rp[1];
status = _gpgme_io_spawn (pgmname, argv, cfd, NULL); status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL);
if (status < 0) if (status < 0)
{ {
_gpgme_io_close (rp[0]); _gpgme_io_close (rp[0]);

View File

@ -377,7 +377,7 @@ inquire_cb (engine_llass_t llass, const char *keyword, const char *args)
if (llass->opt.gpg_agent && !strcmp (keyword, "PINENTRY_LAUNCHED")) if (llass->opt.gpg_agent && !strcmp (keyword, "PINENTRY_LAUNCHED"))
{ {
_gpgme_allow_set_foregound_window ((pid_t)strtoul (args, NULL, 10)); _gpgme_allow_set_foreground_window ((pid_t)strtoul (args, NULL, 10));
} }
if (llass->user.inq_cb) if (llass->user.inq_cb)

View File

@ -1328,7 +1328,9 @@ start (engine_gpg_t gpg)
fd_list[n].dup_to = -1; fd_list[n].dup_to = -1;
status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name : status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
_gpgme_get_gpg_path (), gpg->argv, fd_list, &pid); _gpgme_get_gpg_path (), gpg->argv,
IOSPAWN_FLAG_ALLOW_SET_FG,
fd_list, &pid);
saved_errno = errno; saved_errno = errno;
free (fd_list); free (fd_list);
@ -1376,8 +1378,6 @@ start (engine_gpg_t gpg)
} }
} }
_gpgme_allow_set_foregound_window (pid);
gpg_io_event (gpg, GPGME_EVENT_START, NULL); gpg_io_event (gpg, GPGME_EVENT_START, NULL);
/* fixme: check what data we can release here */ /* fixme: check what data we can release here */

View File

@ -221,7 +221,7 @@ gpgconf_read (void *engine, char *arg1, char *arg2,
cfd[0].fd = rp[1]; cfd[0].fd = rp[1];
status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, NULL); status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
if (status < 0) if (status < 0)
{ {
_gpgme_io_close (rp[0]); _gpgme_io_close (rp[0]);
@ -659,7 +659,7 @@ gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
cfd[0].fd = rp[0]; cfd[0].fd = rp[0];
status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, NULL); status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL);
if (status < 0) if (status < 0)
{ {
_gpgme_io_close (rp[0]); _gpgme_io_close (rp[0]);

View File

@ -292,7 +292,7 @@ default_inq_cb (engine_gpgsm_t gpgsm, const char *line)
{ {
if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17])) if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
{ {
_gpgme_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10)); _gpgme_allow_set_foreground_window ((pid_t)strtoul (line+17, NULL, 10));
} }
return 0; return 0;

View File

@ -34,6 +34,13 @@
#include <process.h> #include <process.h>
#include <windows.h> #include <windows.h>
/* Flag values as used by gpgme. */
#define IOSPAWN_FLAG_ALLOW_SET_FG 1
/* Name of this program. */
#define PGM "gpgme-w32spawn"
struct spawn_fd_item_s struct spawn_fd_item_s
@ -101,7 +108,7 @@ build_commandline (char **argv)
int int
my_spawn (char **argv, struct spawn_fd_item_s *fd_list) my_spawn (char **argv, struct spawn_fd_item_s *fd_list, unsigned int flags)
{ {
SECURITY_ATTRIBUTES sec_attr; SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi = PROCESS_INFORMATION pi =
@ -127,7 +134,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
i = 0; i = 0;
while (argv[i]) while (argv[i])
{ {
fprintf (stderr, "argv[%2i] = %s\n", i, argv[i]); fprintf (stderr, PGM": argv[%2i] = %s\n", i, argv[i]);
i++; i++;
} }
@ -147,7 +154,7 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle (STD_ERROR_HANDLE); si.hStdError = GetStdHandle (STD_ERROR_HANDLE);
fprintf (stderr, "spawning: %s\n", arg_string); fprintf (stderr, PGM": spawning: %s\n", arg_string);
for (i = 0; fd_list[i].handle != -1; i++) for (i = 0; fd_list[i].handle != -1; i++)
{ {
@ -156,19 +163,19 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
{ {
si.hStdInput = (HANDLE) fd_list[i].peer_name; si.hStdInput = (HANDLE) fd_list[i].peer_name;
duped_stdin = 1; duped_stdin = 1;
fprintf (stderr, "dup 0x%x to stdin\n", fd_list[i].peer_name); fprintf (stderr, PGM": dup 0x%x to stdin\n", fd_list[i].peer_name);
} }
else if (fd_list[i].dup_to == 1) else if (fd_list[i].dup_to == 1)
{ {
si.hStdOutput = (HANDLE) fd_list[i].peer_name; si.hStdOutput = (HANDLE) fd_list[i].peer_name;
duped_stdout = 1; duped_stdout = 1;
fprintf (stderr, "dup 0x%x to stdout\n", fd_list[i].peer_name); fprintf (stderr, PGM": dup 0x%x to stdout\n", fd_list[i].peer_name);
} }
else if (fd_list[i].dup_to == 2) else if (fd_list[i].dup_to == 2)
{ {
si.hStdError = (HANDLE) fd_list[i].peer_name; si.hStdError = (HANDLE) fd_list[i].peer_name;
duped_stderr = 1; duped_stderr = 1;
fprintf (stderr, "dup 0x%x to stderr\n", fd_list[i].peer_name); fprintf (stderr, PGM":dup 0x%x to stderr\n", fd_list[i].peer_name);
} }
} }
@ -232,6 +239,33 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
for (i = 0; fd_list[i].handle != -1; i++) for (i = 0; fd_list[i].handle != -1; i++)
CloseHandle ((HANDLE) fd_list[i].handle); CloseHandle ((HANDLE) fd_list[i].handle);
if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
{
static int initialized;
static BOOL (WINAPI * func)(DWORD);
void *handle;
if (!initialized)
{
/* Available since W2000; thus we dynload it. */
initialized = 1;
handle = LoadLibrary ("user32.dll");
if (handle)
{
func = GetProcAddress (handle, "AllowSetForegroundWindow");
if (!func)
FreeLibrary (handle);
}
}
if (func)
{
int rc = func (pi.dwProcessId);
fprintf (stderr, PGM": AllowSetForegroundWindow(%d): rc=%d\n",
(int)pi.dwProcessId, rc);
}
}
ResumeThread (pi.hThread); ResumeThread (pi.hThread);
CloseHandle (pi.hThread); CloseHandle (pi.hThread);
CloseHandle (pi.hProcess); CloseHandle (pi.hProcess);
@ -244,12 +278,13 @@ my_spawn (char **argv, struct spawn_fd_item_s *fd_list)
int int
translate_get_from_file (const char *trans_file, translate_get_from_file (const char *trans_file,
struct spawn_fd_item_s *fd_list) struct spawn_fd_item_s *fd_list,
unsigned int *r_flags)
{ {
/* Hold roughly MAX_TRANS triplets of 64 bit numbers in hex /* Hold roughly MAX_TRANS triplets of 64 bit numbers in hex
notation: "0xFEDCBA9876543210". 10*19*4 - 1 = 759. This plans notation: "0xFEDCBA9876543210". 10*19*4 - 1 = 759. This plans
ahead for a time when a HANDLE is 64 bit. */ ahead for a time when a HANDLE is 64 bit. */
#define BUFFER_MAX 800 #define BUFFER_MAX 810
char line[BUFFER_MAX + 1]; char line[BUFFER_MAX + 1];
char *linep; char *linep;
@ -257,6 +292,8 @@ translate_get_from_file (const char *trans_file,
int res; int res;
int fd; int fd;
*r_flags = 0;
fd = open (trans_file, O_RDONLY); fd = open (trans_file, O_RDONLY);
if (fd < 0) if (fd < 0)
return -1; return -1;
@ -269,10 +306,12 @@ translate_get_from_file (const char *trans_file,
line[BUFFER_MAX] = '\0'; line[BUFFER_MAX] = '\0';
linep = strchr (line, '\n'); linep = strchr (line, '\n');
if (linep)
{
if (linep > line && linep[-1] == '\r') if (linep > line && linep[-1] == '\r')
linep--; linep--;
*linep = '\0'; *linep = '\0';
}
linep = line; linep = line;
/* Now start to read mapping pairs. */ /* Now start to read mapping pairs. */
@ -289,6 +328,21 @@ translate_get_from_file (const char *trans_file,
linep++; linep++;
if (*linep == '\0') if (*linep == '\0')
break; break;
if (!idx && *linep == '~')
{
/* Spawn flags have been passed. */
linep++;
*r_flags = strtoul (linep, &tail, 0);
if (tail == NULL || ! (*tail == '\0' || isspace (*tail)))
break;
linep = tail;
while (isspace (*((unsigned char *)linep)))
linep++;
if (*linep == '\0')
break;
}
from = strtoul (linep, &tail, 0); from = strtoul (linep, &tail, 0);
if (tail == NULL || ! (*tail == '\0' || isspace (*tail))) if (tail == NULL || ! (*tail == '\0' || isspace (*tail)))
break; break;
@ -339,13 +393,14 @@ translate_get_from_file (const char *trans_file,
FD_LIST (which must be MAX_TRANS+1 large). */ FD_LIST (which must be MAX_TRANS+1 large). */
char ** char **
translate_handles (const char *trans_file, const char * const *argv, translate_handles (const char *trans_file, const char * const *argv,
struct spawn_fd_item_s *fd_list) struct spawn_fd_item_s *fd_list, unsigned int *r_flags)
{ {
int res; int res;
int idx; int idx;
int n_args;
char **args; char **args;
res = translate_get_from_file (trans_file, fd_list); res = translate_get_from_file (trans_file, fd_list, r_flags);
if (res < 0) if (res < 0)
return NULL; return NULL;
@ -359,6 +414,7 @@ translate_handles (const char *trans_file, const char * const *argv,
return NULL; return NULL;
} }
args[idx] = NULL; args[idx] = NULL;
n_args = idx;
for (idx = 0; fd_list[idx].handle != -1; idx++) for (idx = 0; fd_list[idx].handle != -1; idx++)
{ {
@ -369,6 +425,12 @@ translate_handles (const char *trans_file, const char * const *argv,
if (aidx == 0) if (aidx == 0)
continue; continue;
if (aidx >= n_args)
{
fprintf (stderr, PGM": translation file does not match args\n");
return NULL;
}
args[aidx] = malloc (sizeof (buf)); args[aidx] = malloc (sizeof (buf));
/* We currently disable translation for stdin/stdout/stderr. We /* We currently disable translation for stdin/stdout/stderr. We
assume that the spawned program handles 0/1/2 specially assume that the spawned program handles 0/1/2 specially
@ -394,6 +456,7 @@ main (int argc, const char * const *argv)
int rc = 0; int rc = 0;
char **argv_spawn; char **argv_spawn;
struct spawn_fd_item_s fd_list[MAX_TRANS + 1]; struct spawn_fd_item_s fd_list[MAX_TRANS + 1];
unsigned int flags;
if (argc < 3) if (argc < 3)
{ {
@ -401,7 +464,7 @@ main (int argc, const char * const *argv)
goto leave; goto leave;
} }
argv_spawn = translate_handles (argv[1], &argv[2], fd_list); argv_spawn = translate_handles (argv[1], &argv[2], fd_list, &flags);
if (!argv_spawn) if (!argv_spawn)
{ {
rc = 2; rc = 2;
@ -411,10 +474,10 @@ main (int argc, const char * const *argv)
/* Using execv does not replace the existing program image, but /* Using execv does not replace the existing program image, but
spawns a new one and daemonizes it, confusing the command line spawns a new one and daemonizes it, confusing the command line
interpreter. So we have to use spawnv. */ interpreter. So we have to use spawnv. */
rc = my_spawn (argv_spawn, fd_list); rc = my_spawn (argv_spawn, fd_list, flags);
if (rc < 0) if (rc < 0)
{ {
fprintf (stderr, "gpgwrap: executing `%s' failed: %s\n", fprintf (stderr, PGM": executing `%s' failed: %s\n",
argv[0], strerror (errno)); argv[0], strerror (errno));
rc = 2; rc = 2;
goto leave; goto leave;
@ -422,12 +485,12 @@ main (int argc, const char * const *argv)
leave: leave:
if (rc) if (rc)
fprintf (stderr, "gpg-w32spawn: internal error\n"); fprintf (stderr, PGM": internal error\n");
/* Always try to delete the temporary file. */ /* Always try to delete the temporary file. */
if (argc >= 2) if (argc >= 2)
{ {
if (DeleteFile (argv[1]) == 0) if (DeleteFile (argv[1]) == 0)
fprintf (stderr, "Failed to delete %s: ec=%ld\n", fprintf (stderr, PGM": failed to delete %s: ec=%ld\n",
argv[1], GetLastError ()); argv[1], GetLastError ());
} }
return rc; return rc;

View File

@ -304,13 +304,16 @@ _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal)
/* Returns 0 on success, -1 on error. */ /* Returns 0 on success, -1 on error. */
int int
_gpgme_io_spawn (const char *path, char *const argv[], _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid) struct spawn_fd_item_s *fd_list, pid_t *r_pid)
{ {
pid_t pid; pid_t pid;
int i; int i;
int status; int status;
int signo; int signo;
(void)flags;
TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path, TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
"path=%s", path); "path=%s", path);
i = 0; i = 0;

View File

@ -67,7 +67,7 @@ _gpgme_get_conf_int (const char *key, int *value)
} }
void void
_gpgme_allow_set_foregound_window (pid_t pid) _gpgme_allow_set_foreground_window (pid_t pid)
{ {
(void)pid; (void)pid;
/* Not needed. */ /* Not needed. */

View File

@ -59,11 +59,15 @@ int _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
void *value); void *value);
int _gpgme_io_set_nonblocking (int fd); int _gpgme_io_set_nonblocking (int fd);
/* A flag to tell the spawn function to allow the child process to set
the foreground window. */
#define IOSPAWN_FLAG_ALLOW_SET_FG 1
/* Spawn the executable PATH with ARGV as arguments. After forking /* Spawn the executable PATH with ARGV as arguments. After forking
close all fds except for those in FD_LIST in the child, then close all fds except for those in FD_LIST in the child, then
optionally dup() the child fds. Finally, all fds in the list are optionally dup() the child fds. Finally, all fds in the list are
closed in the parent. */ closed in the parent. */
int _gpgme_io_spawn (const char *path, char *const argv[], int _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid); struct spawn_fd_item_s *fd_list, pid_t *r_pid);
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock); int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock);

View File

@ -33,7 +33,7 @@ const char *_gpgme_get_gpg_path (void);
const char *_gpgme_get_gpgsm_path (void); const char *_gpgme_get_gpgsm_path (void);
const char *_gpgme_get_gpgconf_path (void); const char *_gpgme_get_gpgconf_path (void);
int _gpgme_get_conf_int (const char *key, int *value); int _gpgme_get_conf_int (const char *key, int *value);
void _gpgme_allow_set_foregound_window (pid_t pid); void _gpgme_allow_set_foreground_window (pid_t pid);
/*-- dirinfo.c --*/ /*-- dirinfo.c --*/
const char *_gpgme_get_default_homedir (void); const char *_gpgme_get_default_homedir (void);

View File

@ -310,7 +310,7 @@ _gpgme_get_program_version (const char *const file_name)
cfd[0].fd = rp[1]; cfd[0].fd = rp[1];
status = _gpgme_io_spawn (file_name, argv, cfd, NULL); status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL);
if (status < 0) if (status < 0)
{ {
_gpgme_io_close (rp[0]); _gpgme_io_close (rp[0]);

View File

@ -584,7 +584,7 @@ build_commandline (char **argv)
int int
_gpgme_io_spawn (const char *path, char * const argv[], _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid) struct spawn_fd_item_s *fd_list, pid_t *r_pid)
{ {
SECURITY_ATTRIBUTES sec_attr; SECURITY_ATTRIBUTES sec_attr;
@ -596,8 +596,8 @@ _gpgme_io_spawn (const char *path, char * const argv[],
0 /* returns tid */ 0 /* returns tid */
}; };
STARTUPINFO si; STARTUPINFO si;
int cr_flags = CREATE_DEFAULT_ERROR_MODE int cr_flags = (CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ()); | GetPriorityClass (GetCurrentProcess ()));
int i; int i;
char **args; char **args;
char *arg_string; char *arg_string;
@ -679,6 +679,9 @@ _gpgme_io_spawn (const char *path, char * const argv[],
free (arg_string); free (arg_string);
if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
_gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);
/* Insert the inherited handles. */ /* Insert the inherited handles. */
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
@ -721,8 +724,10 @@ _gpgme_io_spawn (const char *path, char * const argv[],
int written; int written;
size_t len; size_t len;
line[0] = '\n'; if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG))
line[1] = '\0'; strcpy (line, "~1 \n");
else
strcpy (line, "\n");
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
/* Strip the newline. */ /* Strip the newline. */

View File

@ -1009,7 +1009,7 @@ build_commandline (char **argv)
int int
_gpgme_io_spawn (const char *path, char *const argv[], _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid) struct spawn_fd_item_s *fd_list, pid_t *r_pid)
{ {
SECURITY_ATTRIBUTES sec_attr; SECURITY_ATTRIBUTES sec_attr;
@ -1021,8 +1021,8 @@ _gpgme_io_spawn (const char *path, char *const argv[],
0 /* returns tid */ 0 /* returns tid */
}; };
STARTUPINFO si; STARTUPINFO si;
int cr_flags = CREATE_DEFAULT_ERROR_MODE int cr_flags = (CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ()); | GetPriorityClass (GetCurrentProcess ()));
int i; int i;
char **args; char **args;
char *arg_string; char *arg_string;
@ -1104,6 +1104,9 @@ _gpgme_io_spawn (const char *path, char *const argv[],
free (arg_string); free (arg_string);
if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
_gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);
/* Insert the inherited handles. */ /* Insert the inherited handles. */
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
@ -1139,14 +1142,16 @@ _gpgme_io_spawn (const char *path, char *const argv[],
notation: "0xFEDCBA9876543210" with an extra white space after notation: "0xFEDCBA9876543210" with an extra white space after
every quadruplet. 10*(19*4 + 1) - 1 = 769. This plans ahead every quadruplet. 10*(19*4 + 1) - 1 = 769. This plans ahead
for a time when a HANDLE is 64 bit. */ for a time when a HANDLE is 64 bit. */
#define BUFFER_MAX 800 #define BUFFER_MAX 810
char line[BUFFER_MAX + 1]; char line[BUFFER_MAX + 1];
int res; int res;
int written; int written;
size_t len; size_t len;
line[0] = '\n'; if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG))
line[1] = '\0'; strcpy (line, "~1 \n");
else
strcpy (line, "\n");
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
/* Strip the newline. */ /* Strip the newline. */
@ -1182,6 +1187,7 @@ _gpgme_io_spawn (const char *path, char *const argv[],
if (r_pid) if (r_pid)
*r_pid = (pid_t)pi.dwProcessId; *r_pid = (pid_t)pi.dwProcessId;
if (ResumeThread (pi.hThread) < 0) if (ResumeThread (pi.hThread) < 0)
TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ()); TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());

View File

@ -397,7 +397,7 @@ build_commandline (char **argv)
int int
_gpgme_io_spawn (const char *path, char * const argv[], _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
struct spawn_fd_item_s *fd_list, pid_t *r_pid) struct spawn_fd_item_s *fd_list, pid_t *r_pid)
{ {
SECURITY_ATTRIBUTES sec_attr; SECURITY_ATTRIBUTES sec_attr;
@ -492,6 +492,9 @@ _gpgme_io_spawn (const char *path, char * const argv[],
free (arg_string); free (arg_string);
if (flags & IOSPAWN_FLAG_ALLOW_SET_FG)
_gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId);
/* Insert the inherited handles. */ /* Insert the inherited handles. */
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
@ -533,8 +536,10 @@ _gpgme_io_spawn (const char *path, char * const argv[],
int written; int written;
size_t len; size_t len;
line[0] = '\n'; if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG))
line[1] = '\0'; strcpy (line, "~1 \n");
else
strcpy (line, "\n");
for (i = 0; fd_list[i].fd != -1; i++) for (i = 0; fd_list[i].fd != -1; i++)
{ {
/* Strip the newline. */ /* Strip the newline. */

View File

@ -393,7 +393,7 @@ _gpgme_get_conf_int (const char *key, int *value)
void void
_gpgme_allow_set_foregound_window (pid_t pid) _gpgme_allow_set_foreground_window (pid_t pid)
{ {
static int initialized; static int initialized;
static BOOL (WINAPI * func)(DWORD); static BOOL (WINAPI * func)(DWORD);
@ -416,9 +416,22 @@ _gpgme_allow_set_foregound_window (pid_t pid)
} }
if (!pid || pid == (pid_t)(-1)) if (!pid || pid == (pid_t)(-1))
; {
TRACE1 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
"no action for pid %d", (int)pid);
}
else if (func) else if (func)
func (pid); {
int rc = func (pid);
TRACE2 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
"called for pid %d; result=%d", (int)pid, rc);
}
else
{
TRACE0 (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
"function not available");
}
} }