mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
More changes for CE. gpgsm does now build and run a keylisting.
This commit is contained in:
parent
d1591a97f4
commit
f080b353ed
28 changed files with 595 additions and 329 deletions
|
@ -1,3 +1,34 @@
|
|||
2010-03-24 Werner Koch <wk@g10code.com>
|
||||
|
||||
* stringhelp.c (change_slashes, compare_filenames): Replace
|
||||
HAVE_DRIVE_LETTERS by HAVE_DOSISH_SYSTEM.
|
||||
(make_basename, make_dirname): Detect backslashes and drive
|
||||
letters separately.
|
||||
|
||||
* dotlock.c (make_dotlock, create_dotlock, release_dotlock): Use
|
||||
LockFileEx and UnlockFileEx to support W32CE.
|
||||
|
||||
* ttyio.c (USE_W32_CONSOLE): Replace all _WIN32 by this.
|
||||
(init_ttyfp) [W32CE]: Use stderr.
|
||||
|
||||
* iobuf.c (FD_FOR_STDIN, FD_FOR_STDOUT) [W32CE]: Use estream.
|
||||
(translate_file_handle) [W32CE]: Remove handle translation.
|
||||
|
||||
2010-03-23 Werner Koch <wk@g10code.com>
|
||||
|
||||
* sysutils.c (gnupg_remove): New.
|
||||
|
||||
2010-03-22 Werner Koch <wk@g10code.com>
|
||||
|
||||
* exechelp-w32ce.c (build_w32_commandline): Replace by code from
|
||||
libassuan.
|
||||
(create_inheritable_pipe): Use _assuan_w32ce_prepare_pipe.
|
||||
(build_w32_commandline_copy, do_create_pipe): Remove.
|
||||
|
||||
* exechelp-posix.c (gnupg_spawn_process): Change to use estream
|
||||
also for INFILE and STATUSFILE.
|
||||
* exechelp-w32.c (gnupg_spawn_process): Ditto.
|
||||
|
||||
2010-03-22 Werner Koch <wk@g10code.com>
|
||||
|
||||
* exechelp.c: Remove after factoring all code out to ...
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* dotlock.c - dotfile locking
|
||||
* Copyright (C) 1998, 2000, 2001, 2003, 2004,
|
||||
* 2005, 2006, 2008 Free Software Foundation, Inc.
|
||||
* 2005, 2006, 2008, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of JNLIB.
|
||||
*
|
||||
|
@ -362,7 +362,10 @@ destroy_dotlock (dotlock_t h)
|
|||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if (h->locked)
|
||||
{
|
||||
UnlockFile (h->lockhd, 0, 0, 1, 0);
|
||||
OVERLAPPED ovl;
|
||||
|
||||
memset (&ovl, 0, sizeof ovl);
|
||||
UnlockFileEx (h->lockhd, 0, 1, 0, &ovl);
|
||||
}
|
||||
CloseHandle (h->lockhd);
|
||||
#else /* !HAVE_DOSISH_SYSTEM */
|
||||
|
@ -497,8 +500,12 @@ make_dotlock (dotlock_t h, long timeout)
|
|||
return -1;
|
||||
#else /*HAVE_DOSISH_SYSTEM*/
|
||||
int w32err;
|
||||
OVERLAPPED ovl;
|
||||
|
||||
if (LockFile (h->lockhd, 0, 0, 1, 0))
|
||||
/* Lock one byte at offset 0. The offset is given by OVL. */
|
||||
memset (&ovl, 0, sizeof ovl);
|
||||
if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
|
||||
| LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
|
||||
{
|
||||
h->locked = 1;
|
||||
return 0; /* okay */
|
||||
|
@ -552,12 +559,17 @@ release_dotlock (dotlock_t h)
|
|||
}
|
||||
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if (!UnlockFile (h->lockhd, 0, 0, 1, 0))
|
||||
{
|
||||
log_error ("release_dotlock: error removing lockfile `%s': %s\n",
|
||||
h->lockname, w32_strerror (-1));
|
||||
return -1;
|
||||
}
|
||||
{
|
||||
OVERLAPPED ovl;
|
||||
|
||||
memset (&ovl, 0, sizeof ovl);
|
||||
if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
|
||||
{
|
||||
log_error ("release_dotlock: error removing lockfile `%s': %s\n",
|
||||
h->lockname, w32_strerror (-1));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
pid = read_lockfile (h, &same_node);
|
||||
|
|
|
@ -299,31 +299,12 @@ gnupg_create_outbound_pipe (int filedes[2])
|
|||
}
|
||||
|
||||
|
||||
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||
stdin, write the output to OUTFILE, return a new stream in
|
||||
STATUSFILE for stderr and the pid of the process in PID. The
|
||||
arguments for the process are expected in the NULL terminated array
|
||||
ARGV. The program name itself should not be included there. If
|
||||
PREEXEC is not NULL, that function will be called right before the
|
||||
exec. Calling gnupg_wait_process is required.
|
||||
|
||||
FLAGS is a bit vector with just one bit defined for now:
|
||||
|
||||
Bit 7: If set the process will be started as a background process.
|
||||
This flag is only useful under W32 systems, so that no new
|
||||
console is created and pops up a console window when
|
||||
starting the server
|
||||
|
||||
Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to
|
||||
error problems this actually allows SetForegroundWindow for
|
||||
childs of this process.
|
||||
|
||||
Returns 0 on success or an error code. */
|
||||
/* Fork and exec the PGMNAME, see exechelp.h for details. */
|
||||
gpg_error_t
|
||||
gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||
FILE *infile, estream_t outfile,
|
||||
estream_t infile, estream_t outfile,
|
||||
void (*preexec)(void), unsigned int flags,
|
||||
FILE **statusfile, pid_t *pid)
|
||||
estream_t *statusfile, pid_t *pid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
int fd, fdout, rp[2];
|
||||
|
@ -332,9 +313,9 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||
|
||||
*statusfile = NULL;
|
||||
*pid = (pid_t)(-1);
|
||||
fflush (infile);
|
||||
rewind (infile);
|
||||
fd = fileno (infile);
|
||||
es_fflush (infile);
|
||||
es_rewind (infile);
|
||||
fd = es_fileno (infile);
|
||||
fdout = es_fileno (outfile);
|
||||
if (fd == -1 || fdout == -1)
|
||||
log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
|
||||
|
@ -371,7 +352,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||
/* Parent. */
|
||||
close (rp[1]);
|
||||
|
||||
*statusfile = fdopen (rp[0], "r");
|
||||
*statusfile = es_fdopen (rp[0], "r");
|
||||
if (!*statusfile)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
|
|
|
@ -362,31 +362,12 @@ gnupg_create_outbound_pipe (int filedes[2])
|
|||
}
|
||||
|
||||
|
||||
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||
stdin, write the output to OUTFILE, return a new stream in
|
||||
STATUSFILE for stderr and the pid of the process in PID. The
|
||||
arguments for the process are expected in the NULL terminated array
|
||||
ARGV. The program name itself should not be included there. If
|
||||
PREEXEC is not NULL, that function will be called right before the
|
||||
exec. Calling gnupg_wait_process is required.
|
||||
|
||||
FLAGS is a bit vector with just one bit defined for now:
|
||||
|
||||
Bit 7: If set the process will be started as a background process.
|
||||
This flag is only useful under W32 systems, so that no new
|
||||
console is created and pops up a console window when
|
||||
starting the server
|
||||
|
||||
Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to
|
||||
error problems this actually allows SetForegroundWindow for
|
||||
childs of this process.
|
||||
|
||||
Returns 0 on success or an error code. */
|
||||
/* Fork and exec the PGMNAME, see exechelp.h for details. */
|
||||
gpg_error_t
|
||||
gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||
FILE *infile, estream_t outfile,
|
||||
estream_t infile, estream_t outfile,
|
||||
void (*preexec)(void), unsigned int flags,
|
||||
FILE **statusfile, pid_t *pid)
|
||||
estream_t *statusfile, pid_t *pid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
|
@ -407,9 +388,9 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||
/* Setup return values. */
|
||||
*statusfile = NULL;
|
||||
*pid = (pid_t)(-1);
|
||||
fflush (infile);
|
||||
rewind (infile);
|
||||
fd = _get_osfhandle (fileno (infile));
|
||||
es_fflush (infile);
|
||||
es_rewind (infile);
|
||||
fd = _get_osfhandle (es_fileno (infile));
|
||||
fdout = _get_osfhandle (es_fileno (outfile));
|
||||
if (fd == -1 || fdout == -1)
|
||||
log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
|
||||
|
@ -494,7 +475,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||
if (x == -1)
|
||||
log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
|
||||
else
|
||||
*statusfile = fdopen (x, "r");
|
||||
*statusfile = es_fdopen (x, "r");
|
||||
}
|
||||
if (!*statusfile)
|
||||
{
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <assuan.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "i18n.h"
|
||||
|
@ -71,7 +72,128 @@
|
|||
#define pid_to_handle(a) ((HANDLE)(a))
|
||||
#define handle_to_pid(a) ((int)(a))
|
||||
|
||||
|
||||
#ifdef USE_GNU_PTH
|
||||
/* The data passed to the feeder_thread. */
|
||||
struct feeder_thread_parms
|
||||
{
|
||||
estream_t stream;
|
||||
int fd;
|
||||
int direction;
|
||||
};
|
||||
|
||||
|
||||
/* The thread started by start_feeded. */
|
||||
static void *
|
||||
feeder_thread (void *arg)
|
||||
{
|
||||
struct feeder_thread_parms *parm = arg;
|
||||
char buffer[4096];
|
||||
|
||||
if (parm->direction)
|
||||
{
|
||||
size_t nread;
|
||||
DWORD nwritten;
|
||||
|
||||
while (!es_read (parm->stream, buffer, sizeof buffer, &nread))
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!WriteFile (fd_to_handle (parm->fd),
|
||||
buffer, nread, &nwritten, NULL))
|
||||
{
|
||||
log_debug ("feeder(%d): WriteFile error: rc=%d\n",
|
||||
parm->fd, (int)GetLastError ());
|
||||
goto leave;
|
||||
}
|
||||
nread -= nwritten;
|
||||
}
|
||||
while (nread);
|
||||
}
|
||||
if (nread)
|
||||
log_debug ("feeder(%d): es_read error: %s\n",
|
||||
parm->fd, strerror (errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD nread;
|
||||
size_t nwritten;
|
||||
|
||||
while (ReadFile (fd_to_handle (parm->fd),
|
||||
buffer, sizeof buffer, &nread, NULL) && nread)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (es_write (parm->stream, buffer, nread, &nwritten))
|
||||
{
|
||||
log_debug ("feeder(%d): es_write error: %s\n",
|
||||
parm->fd, strerror (errno));
|
||||
goto leave;
|
||||
}
|
||||
nread -= nwritten;
|
||||
}
|
||||
while (nread);
|
||||
}
|
||||
if (nread)
|
||||
log_debug ("feeder(%d): ReadFile error: rc=%d\n",
|
||||
parm->fd, (int)GetLastError ());
|
||||
else
|
||||
log_debug ("feeder(%d): eof\n", parm->fd);
|
||||
}
|
||||
|
||||
leave:
|
||||
CloseHandle (fd_to_handle (parm->fd));
|
||||
xfree (parm);
|
||||
return NULL;
|
||||
}
|
||||
#endif /*USE_GNU_PTH*/
|
||||
|
||||
/* Fire up a thread to copy data between STREAM and a pipe's
|
||||
descriptor FD. With DIRECTION set to true the copy takes place
|
||||
from the stream to the pipe, otherwise from the pipe to the
|
||||
stream. */
|
||||
static gpg_error_t
|
||||
start_feeder (estream_t stream, int fd, int direction)
|
||||
{
|
||||
#ifdef USE_GNU_PTH
|
||||
gpg_error_t err;
|
||||
struct feeder_thread_parms *parm;
|
||||
pth_attr_t tattr;
|
||||
|
||||
parm = xtrymalloc (sizeof *parm);
|
||||
if (!parm)
|
||||
return gpg_error_from_syserror ();
|
||||
parm->stream = stream;
|
||||
parm->fd = fd;
|
||||
parm->direction = direction;
|
||||
|
||||
tattr = pth_attr_new ();
|
||||
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
|
||||
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024);
|
||||
pth_attr_set (tattr, PTH_ATTR_NAME, "exec-feeder");
|
||||
|
||||
log_error ("spawning new feeder(%p, %d, %d)\n", stream, fd, direction);
|
||||
if(!pth_spawn (tattr, feeder_thread, parm))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error spawning feeder: %s\n", gpg_strerror (err));
|
||||
xfree (parm);
|
||||
}
|
||||
else
|
||||
err = 0;
|
||||
pth_attr_destroy (tattr);
|
||||
|
||||
return err;
|
||||
#else
|
||||
(void)stream;
|
||||
(void)fd;
|
||||
(void)direction;
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* No Pth. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return the maximum number of currently allowed open file
|
||||
descriptors. Only useful on POSIX systems but returns a value on
|
||||
other systems too. */
|
||||
|
@ -182,20 +304,18 @@ get_all_open_fds (void)
|
|||
}
|
||||
|
||||
|
||||
/* Helper function to build_w32_commandline. */
|
||||
|
||||
static char *
|
||||
build_w32_commandline_copy (char *buffer, const char *string)
|
||||
copy_quoted (char *p, const char *string)
|
||||
{
|
||||
char *p = buffer;
|
||||
const char *s;
|
||||
|
||||
if (!*string) /* Empty string. */
|
||||
p = stpcpy (p, "\"\"");
|
||||
else if (strpbrk (string, " \t\n\v\f\""))
|
||||
else if (strpbrk (string, " \t\n\v\f\"")) /* Need quotes. */
|
||||
{
|
||||
/* Need to do some kind of quoting. */
|
||||
p = stpcpy (p, "\"");
|
||||
for (s=string; *s; s++)
|
||||
for (s = string; *s; s++)
|
||||
{
|
||||
*p++ = *s;
|
||||
if (*s == '\"')
|
||||
|
@ -204,32 +324,52 @@ build_w32_commandline_copy (char *buffer, const char *string)
|
|||
*p++ = '\"';
|
||||
*p = 0;
|
||||
}
|
||||
else
|
||||
else /* Copy verbatim. */
|
||||
p = stpcpy (p, string);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Build a command line for use with W32's CreateProcess. On success
|
||||
CMDLINE gets the address of a newly allocated string. */
|
||||
static gpg_error_t
|
||||
build_w32_commandline (const char *pgmname, const char * const *argv,
|
||||
static int
|
||||
build_w32_commandline (const char *pgmname, const char * const *argv,
|
||||
int fd0, int fd1, int fd2, int fd2_isnull,
|
||||
char **cmdline)
|
||||
{
|
||||
int i, n;
|
||||
const char *s;
|
||||
char *buf, *p;
|
||||
char fdbuf[3*30];
|
||||
|
||||
*cmdline = NULL;
|
||||
n = 0;
|
||||
s = pgmname;
|
||||
n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
|
||||
for (; *s; s++)
|
||||
if (*s == '\"')
|
||||
n++; /* Need to double inner quotes. */
|
||||
for (i=0; (s=argv[i]); i++)
|
||||
p = fdbuf;
|
||||
*p = 0;
|
||||
if (fd0)
|
||||
{
|
||||
n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
|
||||
snprintf (p, 25, "-&S0=%d ", fd0);
|
||||
p += strlen (p);
|
||||
}
|
||||
if (fd1)
|
||||
{
|
||||
snprintf (p, 25, "-&S1=%d ", fd1);
|
||||
p += strlen (p);
|
||||
}
|
||||
if (fd2)
|
||||
{
|
||||
if (fd2_isnull)
|
||||
strcpy (p, "-&S2=null ");
|
||||
else
|
||||
snprintf (p, 25, "-&S2=%d ", fd2);
|
||||
p += strlen (p);
|
||||
}
|
||||
|
||||
*cmdline = NULL;
|
||||
n = strlen (fdbuf);
|
||||
n += strlen (pgmname) + 1 + 2; /* (1 space, 2 quoting) */
|
||||
for (i=0; (s = argv[i]); i++)
|
||||
{
|
||||
n += strlen (s) + 1 + 2; /* (1 space, 2 quoting) */
|
||||
for (; *s; s++)
|
||||
if (*s == '\"')
|
||||
n++; /* Need to double inner quotes. */
|
||||
|
@ -237,229 +377,203 @@ build_w32_commandline (const char *pgmname, const char * const *argv,
|
|||
n++;
|
||||
|
||||
buf = p = xtrymalloc (n);
|
||||
if (!buf)
|
||||
return gpg_error_from_syserror ();
|
||||
if (! buf)
|
||||
return -1;
|
||||
|
||||
p = build_w32_commandline_copy (p, pgmname);
|
||||
for (i=0; argv[i]; i++)
|
||||
p = stpcpy (p, fdbuf);
|
||||
p = copy_quoted (p, pgmname);
|
||||
for (i = 0; argv[i]; i++)
|
||||
{
|
||||
*p++ = ' ';
|
||||
p = build_w32_commandline_copy (p, argv[i]);
|
||||
p = copy_quoted (p, argv[i]);
|
||||
}
|
||||
|
||||
*cmdline= buf;
|
||||
*cmdline = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create pipe where one end is inheritable: With an INHERIT_IDX of 0
|
||||
the read end is inheritable, with 1 the write end is inheritable. */
|
||||
static int
|
||||
the read end is inheritable, with 1 the write end is inheritable.
|
||||
Note that the inheritable ends are rendezvous ids and no file
|
||||
descriptors or handles. */
|
||||
static gpg_error_t
|
||||
create_inheritable_pipe (int filedes[2], int inherit_idx)
|
||||
{
|
||||
HANDLE r, w, h;
|
||||
HANDLE hd;
|
||||
int rvid;
|
||||
|
||||
if (!CreatePipe (&r, &w, NULL, 0))
|
||||
return -1;
|
||||
|
||||
if (!DuplicateHandle (GetCurrentProcess(), inherit_idx? w : r,
|
||||
GetCurrentProcess(), &h, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS ))
|
||||
filedes[0] = filedes[1] = -1;
|
||||
hd = _assuan_w32ce_prepare_pipe (&rvid, !inherit_idx);
|
||||
if (hd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1));
|
||||
CloseHandle (r);
|
||||
CloseHandle (w);
|
||||
return -1;
|
||||
log_error ("_assuan_w32ce_prepare_pipe failed: %s\n", w32_strerror (-1));
|
||||
gpg_err_set_errno (EIO);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
if (inherit_idx)
|
||||
{
|
||||
CloseHandle (w);
|
||||
w = h;
|
||||
filedes[0] = handle_to_fd (hd);
|
||||
filedes[1] = rvid;
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle (r);
|
||||
r = h;
|
||||
filedes[0] = rvid;
|
||||
filedes[1] = handle_to_fd (hd);
|
||||
}
|
||||
|
||||
filedes[0] = handle_to_fd (r);
|
||||
filedes[1] = handle_to_fd (w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpg_error_t
|
||||
do_create_pipe (int filedes[2], int inherit_idx)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
int fds[2];
|
||||
|
||||
filedes[0] = filedes[1] = -1;
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
if (!create_inheritable_pipe (fds, inherit_idx))
|
||||
{
|
||||
filedes[0] = _open_osfhandle (fds[0], 0);
|
||||
if (filedes[0] == -1)
|
||||
{
|
||||
log_error ("failed to translate osfhandle %p\n", (void*)fds[0]);
|
||||
CloseHandle (fd_to_handle (fds[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
filedes[1] = _open_osfhandle (fds[1], 1);
|
||||
if (filedes[1] == -1)
|
||||
{
|
||||
log_error ("failed to translate osfhandle %p\n", (void*)fds[1]);
|
||||
close (filedes[0]);
|
||||
filedes[0] = -1;
|
||||
CloseHandle (fd_to_handle (fds[1]));
|
||||
}
|
||||
else
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Portable function to create a pipe. Under Windows the write end is
|
||||
inheritable. */
|
||||
inheritable (i.e. an rendezvous id). */
|
||||
gpg_error_t
|
||||
gnupg_create_inbound_pipe (int filedes[2])
|
||||
{
|
||||
return do_create_pipe (filedes, 1);
|
||||
return create_inheritable_pipe (filedes, 1);
|
||||
}
|
||||
|
||||
|
||||
/* Portable function to create a pipe. Under Windows the read end is
|
||||
inheritable. */
|
||||
inheritable (i.e. an rendezvous id). */
|
||||
gpg_error_t
|
||||
gnupg_create_outbound_pipe (int filedes[2])
|
||||
{
|
||||
return do_create_pipe (filedes, 0);
|
||||
return create_inheritable_pipe (filedes, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||
stdin, write the output to OUTFILE, return a new stream in
|
||||
STATUSFILE for stderr and the pid of the process in PID. The
|
||||
arguments for the process are expected in the NULL terminated array
|
||||
ARGV. The program name itself should not be included there. If
|
||||
PREEXEC is not NULL, that function will be called right before the
|
||||
exec. Calling gnupg_wait_process is required.
|
||||
static int
|
||||
create_process (const char *pgmname, const char *cmdline,
|
||||
PROCESS_INFORMATION *pi)
|
||||
{
|
||||
int res;
|
||||
wchar_t *wpgmname, *wcmdline;
|
||||
|
||||
FLAGS is a bit vector with just one bit defined for now:
|
||||
wpgmname = utf8_to_wchar (pgmname);
|
||||
if (!wpgmname)
|
||||
return 0;
|
||||
wcmdline = utf8_to_wchar (cmdline);
|
||||
if (!wcmdline)
|
||||
{
|
||||
xfree (wpgmname);
|
||||
return 0;
|
||||
}
|
||||
res = CreateProcess (wpgmname, /* Program to start. */
|
||||
wcmdline, /* Command line arguments. */
|
||||
NULL, /* Process security attributes. */
|
||||
NULL, /* Thread security attributes. */
|
||||
FALSE, /* Inherit handles. */
|
||||
CREATE_SUSPENDED, /* Creation flags. */
|
||||
NULL, /* Environment. */
|
||||
NULL, /* Use current drive/directory. */
|
||||
NULL, /* Startup information. */
|
||||
pi); /* Returns process information. */
|
||||
xfree (wcmdline);
|
||||
xfree (wpgmname);
|
||||
return res;
|
||||
}
|
||||
|
||||
Bit 7: If set the process will be started as a background process.
|
||||
This flag is only useful under W32 systems, so that no new
|
||||
console is created and pops up a console window when
|
||||
starting the server. Does not work on W32CE.
|
||||
|
||||
Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to
|
||||
error problems this actually allows SetForegroundWindow for
|
||||
childs of this process.
|
||||
|
||||
Returns 0 on success or an error code. */
|
||||
/* Fork and exec the PGMNAME, see exechelp.h for details. */
|
||||
gpg_error_t
|
||||
gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||
FILE *infile, estream_t outfile,
|
||||
estream_t infile, estream_t outfile,
|
||||
void (*preexec)(void), unsigned int flags,
|
||||
FILE **statusfile, pid_t *pid)
|
||||
estream_t *statusfile, pid_t *pid)
|
||||
{
|
||||
gpg_error_t err;
|
||||
PROCESS_INFORMATION pi =
|
||||
{
|
||||
NULL, /* Returns process handle. */
|
||||
0, /* Returns primary thread handle. */
|
||||
0, /* Returns pid. */
|
||||
0 /* Returns tid. */
|
||||
};
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi = {NULL };
|
||||
char *cmdline;
|
||||
int fd, fdout, rp[2];
|
||||
int inpipe[2], outpipe[2], errpipe[2];
|
||||
|
||||
(void)preexec;
|
||||
|
||||
(void)flags;
|
||||
|
||||
/* Setup return values. */
|
||||
*statusfile = NULL;
|
||||
*pid = (pid_t)(-1);
|
||||
fflush (infile);
|
||||
rewind (infile);
|
||||
fd = _get_osfhandle (fileno (infile));
|
||||
fdout = _get_osfhandle (es_fileno (outfile));
|
||||
if (fd == -1 || fdout == -1)
|
||||
log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n");
|
||||
|
||||
/* Build the command line. */
|
||||
err = build_w32_commandline (pgmname, argv, &cmdline);
|
||||
es_fflush (infile);
|
||||
es_rewind (infile);
|
||||
|
||||
/* Create a pipe to copy our infile to the stdin of the child
|
||||
process. On success inpipe[1] is owned by the feeder. */
|
||||
err = create_inheritable_pipe (inpipe, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Create a pipe. */
|
||||
if (create_inheritable_pipe (rp, 1))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
||||
xfree (cmdline);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Start the process. Note that we can't run the PREEXEC function
|
||||
because this would change our own environment. */
|
||||
/* si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; */
|
||||
/* si.hStdInput = fd_to_handle (fd); */
|
||||
/* si.hStdOutput = fd_to_handle (fdout); */
|
||||
/* si.hStdError = fd_to_handle (rp[1]); */
|
||||
err = start_feeder (infile, inpipe[1], 1);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error spawning feeder: %s\n"), gpg_strerror (err));
|
||||
CloseHandle (fd_to_handle (inpipe[1]));
|
||||
return err;
|
||||
}
|
||||
|
||||
/* log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); */
|
||||
if (!CreateProcess (pgmname, /* Program to start. */
|
||||
cmdline, /* Command line arguments. */
|
||||
NULL, /* Process security attributes. */
|
||||
NULL, /* Thread security attributes. */
|
||||
FALSE, /* Inherit handles. */
|
||||
CREATE_SUSPENDED, /* Creation flags. */
|
||||
NULL, /* Environment. */
|
||||
NULL, /* Use current drive/directory. */
|
||||
NULL, /* Startup information. */
|
||||
&pi /* Returns process information. */
|
||||
))
|
||||
/* Create a pipe to copy stdout of the child process to our
|
||||
outfile. On success outpipe[0] is owned by the feeded. */
|
||||
err = create_inheritable_pipe (outpipe, 1);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
||||
return err;
|
||||
}
|
||||
err = start_feeder (outfile, outpipe[0], 0);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error spawning feeder: %s\n"), gpg_strerror (err));
|
||||
CloseHandle (fd_to_handle (outpipe[0]));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Create a pipe for use with stderr of the child process. */
|
||||
err = create_inheritable_pipe (errpipe, 1);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Build the command line. */
|
||||
err = build_w32_commandline (pgmname, argv, inpipe[0], outpipe[1], errpipe[1],
|
||||
0, &cmdline);
|
||||
if (err)
|
||||
{
|
||||
CloseHandle (fd_to_handle (errpipe[0]));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline);
|
||||
if (!create_process (pgmname, cmdline, &pi))
|
||||
{
|
||||
log_error ("CreateProcess failed: %s\n", w32_strerror (-1));
|
||||
xfree (cmdline);
|
||||
CloseHandle (fd_to_handle (rp[0]));
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (fd_to_handle (errpipe[0]));
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
xfree (cmdline);
|
||||
cmdline = NULL;
|
||||
|
||||
/* Close the other end of the pipe. */
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
/* Note: The other end of the pipe is a rendezvous id and thus there
|
||||
is no need to close. */
|
||||
|
||||
log_debug ("CreateProcess ready: hProcess=%p hThread=%p"
|
||||
" dwProcessID=%d dwThreadId=%d\n",
|
||||
pi.hProcess, pi.hThread,
|
||||
(int) pi.dwProcessId, (int) pi.dwThreadId);
|
||||
|
||||
/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */
|
||||
/* " dwProcessID=%d dwThreadId=%d\n", */
|
||||
/* pi.hProcess, pi.hThread, */
|
||||
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
|
||||
|
||||
/* Fixme: For unknown reasons AllowSetForegroundWindow returns an
|
||||
invalid argument error if we pass the correct processID to
|
||||
it. As a workaround we use -1 (ASFW_ANY). */
|
||||
if ( (flags & 64) )
|
||||
gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/);
|
||||
|
||||
/* Process has been created suspended; resume it now. */
|
||||
ResumeThread (pi.hThread);
|
||||
CloseHandle (pi.hThread);
|
||||
|
||||
{
|
||||
int x;
|
||||
|
||||
x = _open_osfhandle (rp[0], 0);
|
||||
if (x == -1)
|
||||
log_error ("failed to translate osfhandle %p\n", (void*)rp[0] );
|
||||
else
|
||||
*statusfile = fdopen (x, "r");
|
||||
}
|
||||
*statusfile = es_fdopen (handle_to_fd (errpipe[0]), "r");
|
||||
if (!*statusfile)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
|
@ -487,6 +601,8 @@ gpg_error_t
|
|||
gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
|
||||
int infd, int outfd, int errfd, pid_t *pid)
|
||||
{
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#if 0
|
||||
gpg_error_t err;
|
||||
PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
|
||||
STARTUPINFO si;
|
||||
|
@ -546,10 +662,9 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
|
|||
|
||||
*pid = handle_to_pid (pi.hProcess);
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Wait for the process identified by PID to terminate. PGMNAME should
|
||||
be the same as supplied to the spawn function and is only used for
|
||||
diagnostics. Returns 0 if the process succeeded, GPG_ERR_GENERAL
|
||||
|
@ -628,6 +743,8 @@ gpg_error_t
|
|||
gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
|
||||
const char *envp[] )
|
||||
{
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#if 0
|
||||
gpg_error_t err;
|
||||
PROCESS_INFORMATION pi =
|
||||
{
|
||||
|
@ -678,9 +795,9 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
|
|||
CloseHandle (pi.hThread);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Kill a process; that is send an appropriate signal to the process.
|
||||
gnupg_wait_process must be called to actually remove the process
|
||||
from the system. An invalid PID is ignored. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* exechelp.h - Definitions for the fork and exec helpers
|
||||
* Copyright (C) 2004, 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2004, 2009, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -58,13 +58,25 @@ gpg_error_t gnupg_create_outbound_pipe (int filedes[2]);
|
|||
arguments for the process are expected in the NULL terminated array
|
||||
ARGV. The program name itself should not be included there. If
|
||||
PREEXEC is not NULL, that function will be called right before the
|
||||
exec. FLAGS is currently only useful for W32, see the source for
|
||||
details. Calling gnupg_wait_process is required. Returns 0 on
|
||||
success or an error code. */
|
||||
exec. Calling gnupg_wait_process is required. Returns 0 on
|
||||
success or an error code.
|
||||
|
||||
FLAGS is a bit vector:
|
||||
|
||||
Bit 7: If set the process will be started as a background process.
|
||||
This flag is only useful under W32 (but not W32CE) systems,
|
||||
so that no new console is created and pops up a console
|
||||
window when starting the server. Does not work on W32CE.
|
||||
|
||||
Bit 6: On W32 (but not on W32CE) run AllowSetForegroundWindow for
|
||||
the child. Note that due to unknown problems this actually
|
||||
allows SetForegroundWindow for all childs of this process.
|
||||
|
||||
*/
|
||||
gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
|
||||
FILE *infile, estream_t outfile,
|
||||
estream_t infile, estream_t outfile,
|
||||
void (*preexec)(void), unsigned int flags,
|
||||
FILE **statusfile, pid_t *pid);
|
||||
estream_t *statusfile, pid_t *pid);
|
||||
|
||||
|
||||
/* Simplified version of gnupg_spawn_process. This function forks and
|
||||
|
|
|
@ -101,7 +101,7 @@ init_common_subsystems (int *argcp, char ***argvp)
|
|||
SetStdioPath set and restore game. The caller needs to pass the
|
||||
rendezvous ids using up to three options:
|
||||
|
||||
-&S0=<handle> -&S1=<handle> -&S2=<handle>
|
||||
-&S0=<rvid> -&S1=<rvid> -&S2=<rvid>
|
||||
|
||||
They are all optional but they must be the first arguments on the
|
||||
command line. Parsing stops as soon as an invalid option is found.
|
||||
|
|
|
@ -52,8 +52,13 @@
|
|||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
# define FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
|
||||
# define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
|
||||
# ifdef HAVE_W32CE_SYSTEM
|
||||
# define FD_FOR_STDIN (es_fileno (es_stdin))
|
||||
# define FD_FOR_STDOUT (es_fileno (es_stdout))
|
||||
# else
|
||||
# define FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
|
||||
# define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
|
||||
# endif
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
# define FD_FOR_STDIN (0)
|
||||
# define FD_FOR_STDOUT (1)
|
||||
|
@ -2361,7 +2366,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
|
|||
static int
|
||||
translate_file_handle (int fd, int for_write)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#if defined(HAVE_W32_SYSTEM) && !defined (HAVE_W32CE_SYSTEM)
|
||||
{
|
||||
int x;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* se4ssiobn-env.c - session environment helper functions.
|
||||
/* session-env.c - Session environment helper functions.
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
|
@ -300,7 +300,7 @@ session_env_getenv (session_env_t se, const char *name)
|
|||
/* Return the value of the environment variable NAME from the SE
|
||||
object. The returned value is valid as long as SE is valid and as
|
||||
long it has not been removed or updated by a call to
|
||||
session_env_putenv. If the variable does not exist, the fucntion
|
||||
session_env_putenv. If the variable does not exist, the function
|
||||
tries to return the value trough a call to getenv; if that returns
|
||||
a value, this value is recorded and and used. If no value could be
|
||||
found, returns NULL. The caller must not change the returned
|
||||
|
@ -325,7 +325,7 @@ session_env_getenv_or_default (session_env_t se, const char *name,
|
|||
return se->array[idx]->value;
|
||||
}
|
||||
|
||||
/* Get the default value with and additional fallback for GPG_TTY. */
|
||||
/* Get the default value with an additional fallback for GPG_TTY. */
|
||||
defvalue = getenv (name);
|
||||
if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") && ttyname (0))
|
||||
defvalue = ttyname (0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* stringhelp.c - standard string helper functions
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005,
|
||||
* 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
|
||||
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of JNLIB.
|
||||
*
|
||||
|
@ -48,7 +48,7 @@
|
|||
static inline char *
|
||||
change_slashes (char *name)
|
||||
{
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
char *p;
|
||||
|
||||
if (strchr (name, '\\'))
|
||||
|
@ -57,7 +57,7 @@ change_slashes (char *name)
|
|||
if (*p == '/')
|
||||
*p = '\\';
|
||||
}
|
||||
#endif /*HAVE_DRIVE_LETTERS*/
|
||||
#endif /*HAVE_DOSISH_SYSTEM*/
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -273,8 +273,10 @@ make_basename(const char *filepath, const char *inputpath)
|
|||
(void)inputpath; /* Only required for riscos. */
|
||||
|
||||
if ( !(p=strrchr(filepath, '/')) )
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
#endif
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#endif
|
||||
{
|
||||
|
@ -300,8 +302,10 @@ make_dirname(const char *filepath)
|
|||
char *p;
|
||||
|
||||
if ( !(p=strrchr(filepath, '/')) )
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
if ( !(p=strrchr(filepath, '\\')) )
|
||||
#endif
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
if ( !(p=strrchr(filepath, ':')) )
|
||||
#endif
|
||||
{
|
||||
|
@ -479,12 +483,12 @@ make_filename_try (const char *first_part, ... )
|
|||
/* Compare whether the filenames are identical. This is a
|
||||
special version of strcmp() taking the semantics of filenames in
|
||||
account. Note that this function works only on the supplied names
|
||||
without considereing any context like the current directory. See
|
||||
without considering any context like the current directory. See
|
||||
also same_file_p(). */
|
||||
int
|
||||
compare_filenames (const char *a, const char *b)
|
||||
{
|
||||
#ifdef HAVE_DRIVE_LETTERS
|
||||
#ifdef HAVE_DOSISH_SYSTEM
|
||||
for ( ; *a && *b; a++, b++ )
|
||||
{
|
||||
if (*a != *b
|
||||
|
|
|
@ -505,6 +505,30 @@ gnupg_allow_set_foregound_window (pid_t pid)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
gnupg_remove (const char *fname)
|
||||
{
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
int rc;
|
||||
wchar_t *wfname;
|
||||
|
||||
wfname = utf8_to_wchar (fname);
|
||||
if (!wfname)
|
||||
rc = 0;
|
||||
else
|
||||
{
|
||||
rc = DeleteFile (wfname);
|
||||
xfree (wfname);
|
||||
}
|
||||
if (!rc)
|
||||
gpg_err_set_errno (EIO);
|
||||
return !rc;
|
||||
#else
|
||||
return remove;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
|
|
|
@ -48,7 +48,7 @@ int translate_sys2libc_fd_int (int fd, int for_write);
|
|||
FILE *gnupg_tmpfile (void);
|
||||
void gnupg_reopen_std (const char *pgmname);
|
||||
void gnupg_allow_set_foregound_window (pid_t pid);
|
||||
|
||||
int gnupg_remove (const char *fname);
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
|
||||
# define USE_W32_CONSOLE 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TCGETATTR
|
||||
#include <termios.h>
|
||||
#else
|
||||
|
@ -37,11 +42,11 @@
|
|||
#define HAVE_TCGETATTR
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _WIN32 /* use the odd Win32 functions */
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_TCGETATTR
|
||||
#error mingw32 and termios
|
||||
#endif
|
||||
#ifdef USE_W32_CONSOLE
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_TCGETATTR
|
||||
# error mingw32 and termios
|
||||
# endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
@ -52,7 +57,8 @@
|
|||
|
||||
#define CONTROL_D ('D' - 'A' + 1)
|
||||
|
||||
#ifdef _WIN32 /* use the odd Win32 functions */
|
||||
|
||||
#ifdef USE_W32_CONSOLE
|
||||
static struct {
|
||||
HANDLE in, out;
|
||||
} con;
|
||||
|
@ -116,7 +122,7 @@ tty_get_ttyname (void)
|
|||
}
|
||||
#endif /*HAVE_CTERMID*/
|
||||
/* Assume the standard tty on memory error or when tehre is no
|
||||
certmid. */
|
||||
ctermid. */
|
||||
return name? name : "/dev/tty";
|
||||
}
|
||||
|
||||
|
@ -140,7 +146,7 @@ init_ttyfp(void)
|
|||
if( initialized )
|
||||
return;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(USE_W32_CONSOLE)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
|
||||
|
@ -168,6 +174,8 @@ init_ttyfp(void)
|
|||
ttyfp = stdout; /* Fixme: replace by the real functions: see wklib */
|
||||
if (my_rl_init_stream)
|
||||
my_rl_init_stream (ttyfp);
|
||||
#elif defined (HAVE_W32CE_SYSTEM)
|
||||
ttyfp = stderr;
|
||||
#else
|
||||
ttyfp = batchmode? stderr : fopen (tty_get_ttyname (), "r+");
|
||||
if( !ttyfp ) {
|
||||
|
@ -216,7 +224,7 @@ tty_printf( const char *fmt, ... )
|
|||
init_ttyfp();
|
||||
|
||||
va_start( arg_ptr, fmt ) ;
|
||||
#ifdef _WIN32
|
||||
#ifdef USE_W32_CONSOLE
|
||||
{
|
||||
char *buf = NULL;
|
||||
int n;
|
||||
|
@ -263,7 +271,7 @@ tty_fprintf (estream_t fp, const char *fmt, ... )
|
|||
init_ttyfp ();
|
||||
|
||||
va_start (arg_ptr, fmt);
|
||||
#ifdef _WIN32
|
||||
#ifdef USE_W32_CONSOLE
|
||||
{
|
||||
char *buf = NULL;
|
||||
int n;
|
||||
|
@ -300,7 +308,7 @@ tty_print_string ( const byte *p, size_t n )
|
|||
if( !initialized )
|
||||
init_ttyfp();
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef USE_W32_CONSOLE
|
||||
/* not so effective, change it if you want */
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
|
@ -394,7 +402,7 @@ do_get( const char *prompt, int hidden )
|
|||
buf = xmalloc((n=50));
|
||||
i = 0;
|
||||
|
||||
#ifdef _WIN32 /* windoze version */
|
||||
#ifdef USE_W32_CONSOLE
|
||||
if( hidden )
|
||||
SetConsoleMode(con.in, HID_INPMODE );
|
||||
|
||||
|
@ -428,9 +436,17 @@ do_get( const char *prompt, int hidden )
|
|||
if( hidden )
|
||||
SetConsoleMode(con.in, DEF_INPMODE );
|
||||
|
||||
#elif defined(__riscos__)
|
||||
#elif defined(__riscos__) || defined(HAVE_W32CE_SYSTEM)
|
||||
do {
|
||||
#ifdef HAVE_W32CE_SYSTEM
|
||||
/* Using getchar is not a correct solution but for now it
|
||||
doesn't matter becuase we have no real console at all. We
|
||||
should rework this as soon as we have switched this entire
|
||||
module to estream. */
|
||||
c = getchar();
|
||||
#else
|
||||
c = riscos_getchar();
|
||||
#endif
|
||||
if (c == 0xa || c == 0xd) { /* Return || Enter */
|
||||
c = (int) '\n';
|
||||
} else if (c == 0x8 || c == 0x7f) { /* Backspace || Delete */
|
||||
|
@ -468,7 +484,7 @@ do_get( const char *prompt, int hidden )
|
|||
}
|
||||
} while (c != '\n');
|
||||
i = (i>0) ? i-1 : 0;
|
||||
#else /* unix version */
|
||||
#else /* Other systems. */
|
||||
if( hidden ) {
|
||||
#ifdef HAVE_TCGETATTR
|
||||
struct termios term;
|
||||
|
@ -509,7 +525,6 @@ do_get( const char *prompt, int hidden )
|
|||
i = 1;
|
||||
}
|
||||
|
||||
|
||||
if( hidden ) {
|
||||
#ifdef HAVE_TCGETATTR
|
||||
if( tcsetattr(fileno(ttyfp), TCSAFLUSH, &termsave) )
|
||||
|
@ -601,7 +616,7 @@ tty_kill_prompt()
|
|||
last_prompt_len = 0;
|
||||
if( !last_prompt_len )
|
||||
return;
|
||||
#ifdef _WIN32
|
||||
#ifdef USE_W32_CONSOLE
|
||||
tty_printf("\r%*s\r", last_prompt_len, "");
|
||||
#else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue