summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2022-04-07 10:44:11 +0200
committerWerner Koch <wk@gnupg.org>2022-04-07 10:44:11 +0200
commitff3b2ea8858a7f95633edf0d41d1815048aa8ac8 (patch)
treed7112ccf738440cc87541952068e917e272afb18
parent038d34656f5b4f0075eced12e86e983163d6d881 (diff)
parent74e6afcc36b28b0acc49fbe25f29b42d1a223caf (diff)
downloadlibgpg-error-ff3b2ea8858a7f95633edf0d41d1815048aa8ac8.tar.gz
Merge branch 'master' of ssh+git://playfair.gnupg.org/git/libgpg-error
--
-rw-r--r--doc/yat2m.c3
-rw-r--r--src/estream.c256
-rw-r--r--src/gpg-error.h.in2
-rw-r--r--src/gpgrt-int.h1
-rw-r--r--src/logging.c89
-rw-r--r--src/mkheader.c7
-rw-r--r--src/posix-lock.c36
-rw-r--r--src/spawn-w32.c17
-rw-r--r--src/w32-estream.c4
9 files changed, 336 insertions, 79 deletions
diff --git a/doc/yat2m.c b/doc/yat2m.c
index 10e03ec..8c05ad8 100644
--- a/doc/yat2m.c
+++ b/doc/yat2m.c
@@ -1323,7 +1323,8 @@ finish_page (void)
}
else if (opt_store)
{
- inf ("writing '%s'", thepage.name );
+ if (verbose)
+ inf ("writing '%s'", thepage.name );
fp = fopen ( thepage.name, "w" );
if (!fp)
die ("failed to create '%s': %s\n", thepage.name, strerror (errno));
diff --git a/src/estream.c b/src/estream.c
index 0542f59..32f8f48 100644
--- a/src/estream.c
+++ b/src/estream.c
@@ -1197,12 +1197,214 @@ static struct cookie_io_functions_s estream_functions_fd =
};
+
+#ifdef HAVE_W32_SYSTEM
+/*
+ * Implementation of SOCKET based I/O.
+ */
+
+/* Cookie for SOCKET objects. */
+typedef struct estream_cookie_sock
+{
+ SOCKET sock; /* The SOCKET we are using for actual output. */
+ int no_close; /* If set we won't close the file descriptor. */
+ int nonblock; /* Non-blocking mode is enabled. */
+} *estream_cookie_sock_t;
+
+
+/*
+ * Create function for objects indentified by a libc file descriptor.
+ */
+static int
+func_sock_create (void **cookie, SOCKET sock,
+ unsigned int modeflags, int no_close)
+{
+ estream_cookie_sock_t sock_cookie;
+ int err;
+
+ trace (("enter: sock=%d mf=%x nc=%d", (int)sock, modeflags, no_close));
+
+ sock_cookie = mem_alloc (sizeof (*sock_cookie));
+ if (! sock_cookie)
+ err = -1;
+ else
+ {
+ sock_cookie->sock = sock;
+ sock_cookie->no_close = no_close;
+ sock_cookie->nonblock = !!(modeflags & O_NONBLOCK);
+ *cookie = sock_cookie;
+ err = 0;
+ }
+
+ trace_errno (err, ("leave: cookie=%p err=%d", *cookie, err));
+ return err;
+}
+
+
+/*
+ * Read function for SOCKET objects.
+ */
+static gpgrt_ssize_t
+func_sock_read (void *cookie, void *buffer, size_t size)
+
+{
+ estream_cookie_sock_t file_cookie = cookie;
+ gpgrt_ssize_t bytes_read;
+
+ trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
+ if (!size)
+ bytes_read = -1; /* We don't know whether anything is pending. */
+ else if (IS_INVALID_FD (file_cookie->sock))
+ {
+ _gpgrt_yield ();
+ bytes_read = 0;
+ }
+ else
+ {
+ _gpgrt_pre_syscall ();
+ do
+ {
+ bytes_read = recv (file_cookie->sock, buffer, size, 0);
+ }
+ while (bytes_read == -1 && errno == EINTR);
+ _gpgrt_post_syscall ();
+ }
+ trace_errno (bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read));
+ return bytes_read;
+}
+
+
+/*
+ * Write function for SOCKET objects.
+ */
+static gpgrt_ssize_t
+func_sock_write (void *cookie, const void *buffer, size_t size)
+{
+ estream_cookie_sock_t file_cookie = cookie;
+ gpgrt_ssize_t bytes_written;
+
+ trace (("enter: cookie=%p buffer=%p size=%d", cookie, buffer, (int)size));
+
+ if (IS_INVALID_FD (file_cookie->sock))
+ {
+ _gpgrt_yield ();
+ bytes_written = size; /* Yeah: Success writing to the bit bucket. */
+ }
+ else if (buffer)
+ {
+ _gpgrt_pre_syscall ();
+ do
+ {
+ bytes_written = send (file_cookie->sock, buffer, size, 0);
+ }
+ while (bytes_written == -1 && errno == EINTR);
+ _gpgrt_post_syscall ();
+ }
+ else
+ bytes_written = size; /* Note that for a flush SIZE should be 0. */
+
+ trace_errno (bytes_written == -1,
+ ("leave: bytes_written=%d", (int)bytes_written));
+ return bytes_written;
+}
+
+
+/*
+ * Seek function for SOCKET objects.
+ */
+static int
+func_sock_seek (void *cookie, gpgrt_off_t *offset, int whence)
+{
+ (void)cookie;
+ (void)offset;
+ (void)whence;
+ _set_errno (ESPIPE);
+ return -1;
+}
+
+
+/*
+ * The IOCTL function for SOCKET objects.
+ */
+static int
+func_sock_ioctl (void *cookie, int cmd, void *ptr, size_t *len)
+{
+ estream_cookie_sock_t sock_cookie = cookie;
+ int ret;
+
+ if (cmd == COOKIE_IOCTL_NONBLOCK && !len)
+ {
+ sock_cookie->nonblock = !!ptr;
+ if (IS_INVALID_FD (sock_cookie->sock))
+ {
+ _set_errno (EINVAL);
+ ret = -1;
+ }
+ else
+ {
+ u_long mode = 0;
+
+ if (sock_cookie->nonblock)
+ mode = 1;
+
+ ret = ioctlsocket (sock_cookie->sock, FIONBIO, &mode);
+ }
+ }
+ else
+ {
+ _set_errno (EINVAL);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+/*
+ * The destroy function for SOCKET objects.
+ */
+static int
+func_sock_destroy (void *cookie)
+{
+ estream_cookie_sock_t sock_cookie = cookie;
+ int err;
+
+ trace (("enter: cookie=%p", cookie));
+
+ if (sock_cookie)
+ {
+ if (IS_INVALID_FD (sock_cookie->sock))
+ err = 0;
+ else
+ err = sock_cookie->no_close? 0 : closesocket (sock_cookie->sock);
+ mem_free (sock_cookie);
+ }
+ else
+ err = 0;
+
+ trace_errno (err,("leave: err=%d", err));
+ return err;
+}
+
+
+/*
+ * Access object for the fd functions.
+ */
+static struct cookie_io_functions_s estream_functions_sock =
+ {
+ {
+ func_sock_read,
+ func_sock_write,
+ func_sock_seek,
+ func_sock_destroy,
+ },
+ func_sock_ioctl,
+ };
/*
* Implementation of W32 handle based I/O.
*/
-#ifdef HAVE_W32_SYSTEM
/* Cookie for fd objects. */
typedef struct estream_cookie_w32
@@ -3645,6 +3847,53 @@ _gpgrt_fpopen_nc (FILE *fp, const char *mode)
#ifdef HAVE_W32_SYSTEM
+static estream_t
+do_sockopen (SOCKET sock, const char *mode, int no_close, int with_locked_list)
+{
+ int create_called = 0;
+ estream_t stream = NULL;
+ void *cookie = NULL;
+ unsigned int modeflags, xmode;
+ int err;
+ es_syshd_t syshd;
+
+ err = parse_mode (mode, &modeflags, &xmode, NULL);
+ if (err)
+ goto out;
+ if ((xmode & X_SYSOPEN))
+ {
+ /* Not allowed for sockopen. */
+ _set_errno (EINVAL);
+ err = -1;
+ goto out;
+ }
+
+ err = func_sock_create (&cookie, sock, modeflags, no_close);
+ if (err)
+ goto out;
+
+ syshd.type = ES_SYSHD_SOCK;
+ syshd.u.sock = sock;
+ create_called = 1;
+ err = create_stream (&stream, cookie, &syshd,
+ BACKEND_SOCK, estream_functions_sock,
+ modeflags, xmode, with_locked_list);
+
+ if (!err && stream)
+ {
+ if ((modeflags & O_NONBLOCK))
+ err = stream->intern->func_ioctl (cookie, COOKIE_IOCTL_NONBLOCK,
+ "", NULL);
+ }
+
+ out:
+ if (err && create_called)
+ (*estream_functions_sock.public.func_close) (cookie);
+
+ return stream;
+}
+
+
estream_t
do_w32open (HANDLE hd, const char *mode,
int no_close, int with_locked_list)
@@ -3692,11 +3941,16 @@ do_sysopen (es_syshd_t *syshd, const char *mode, int no_close)
switch (syshd->type)
{
case ES_SYSHD_FD:
+#ifndef HAVE_W32_SYSTEM
case ES_SYSHD_SOCK:
+#endif
stream = do_fdopen (syshd->u.fd, mode, no_close, 0);
break;
#ifdef HAVE_W32_SYSTEM
+ case ES_SYSHD_SOCK:
+ stream = do_sockopen (syshd->u.sock, mode, no_close, 0);
+ break;
case ES_SYSHD_HANDLE:
stream = do_w32open (syshd->u.handle, mode, no_close, 0);
break;
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index b97f38a..ccacf35 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -620,7 +620,7 @@ struct _gpgrt_syshd
enum gpgrt_syshd_types type;
union {
int fd;
- int sock;
+ @SOCKET_t@ sock;
int rvid;
void *handle;
} u;
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index b53ebe9..a541620 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -234,6 +234,7 @@ typedef enum
{
BACKEND_MEM,
BACKEND_FD,
+ BACKEND_SOCK,
BACKEND_W32,
BACKEND_FP,
BACKEND_USER,
diff --git a/src/logging.c b/src/logging.c
index e4b7e40..9bc9350 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -64,10 +64,6 @@
#endif
-#ifdef HAVE_W32CE_SYSTEM
-# define isatty(a) (0)
-#endif
-
#undef WITH_IPV6
#if defined (AF_INET6) && defined(PF_INET) \
&& defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON)
@@ -144,9 +140,6 @@ struct fun_cookie_s
int quiet;
int want_socket;
int is_socket;
-#ifdef HAVE_W32CE_SYSTEM
- int use_writefile;
-#endif
char name[1];
};
@@ -209,9 +202,6 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size)
{
struct fun_cookie_s *cookie = cookie_arg;
- /* FIXME: Use only estream with a callback for socket writing. This
- avoids the ugly mix of fd and estream code. */
-
/* Note that we always try to reconnect to the socket but print
error messages only the first time an error occurred. If
RUNNING_DETACHED is set we don't fall back to stderr and even do
@@ -415,15 +405,6 @@ fun_writer (void *cookie_arg, const void *buffer, size_t size)
log_socket = cookie->fd;
if (cookie->fd != -1)
{
-#ifdef HAVE_W32CE_SYSTEM
- if (cookie->use_writefile)
- {
- DWORD nwritten;
-
- WriteFile ((HANDLE)cookie->fd, buffer, size, &nwritten, NULL);
- return (gpgrt_ssize_t)size; /* Okay. */
- }
-#endif
if (!writen (cookie->fd, buffer, size, cookie->is_socket))
return (gpgrt_ssize_t)size; /* Okay. */
}
@@ -469,9 +450,6 @@ set_file_fd (const char *name, int fd, estream_t stream)
{
estream_t fp;
int want_socket = 0;
-#ifdef HAVE_W32CE_SYSTEM
- int use_writefile = 0;
-#endif
struct fun_cookie_s *cookie;
/* Close an open log stream. */
@@ -492,66 +470,41 @@ set_file_fd (const char *name, int fd, estream_t stream)
/* Figure out what kind of logging we want. */
if (name && !strcmp (name, "-"))
{
- name = NULL;
- fd = _gpgrt_fileno (es_stderr);
+ fp = es_stderr;
+ goto leave;
}
-
- if (name && !strncmp (name, "tcp://", 6) && name[6])
+ else if (name && !strncmp (name, "tcp://", 6) && name[6])
want_socket = 1;
#ifndef HAVE_W32_SYSTEM
else if (name && !strncmp (name, "socket://", 9))
want_socket = 2;
#endif /*HAVE_W32_SYSTEM*/
-#ifdef HAVE_W32CE_SYSTEM
- else if (name && !strcmp (name, "GPG2:"))
- {
- HANDLE hd;
-
- ActivateDevice (L"Drivers\\"GNUPG_NAME"_Log", 0);
- /* Ignore a filename and write the debug output to the GPG2:
- device. */
- hd = CreateFile (L"GPG2:", GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- fd = (hd == INVALID_HANDLE_VALUE)? -1 : (int)hd;
- name = NULL;
- force_prefixes = 1;
- use_writefile = 1;
- }
-#endif /*HAVE_W32CE_SYSTEM*/
/* Setup a new stream. */
- cookie = _gpgrt_malloc (sizeof *cookie + (name? strlen (name):0));
- if (!cookie)
- return; /* oops */
- strcpy (cookie->name, name? name:"");
- cookie->quiet = 0;
- cookie->is_socket = 0;
- cookie->want_socket = want_socket;
-#ifdef HAVE_W32CE_SYSTEM
- cookie->use_writefile = use_writefile;
-#endif
if (!name)
- cookie->fd = fd;
- else if (want_socket)
- cookie->fd = -1;
+ fp = _gpgrt_fdopen (fd, "w");
+ else if (!want_socket)
+ fp = _gpgrt_fopen (name, "a");
else
{
- do
- cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT,
- (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH));
- while (cookie->fd == -1 && errno == EINTR);
- }
- log_socket = cookie->fd;
+ es_cookie_io_functions_t io = { NULL };
- {
- es_cookie_io_functions_t io = { NULL };
- io.func_write = fun_writer;
- io.func_close = fun_closer;
+ cookie = _gpgrt_malloc (sizeof *cookie + (name? strlen (name):0));
+ if (!cookie)
+ return; /* oops */
+ strcpy (cookie->name, name? name:"");
+ cookie->quiet = 0;
+ cookie->is_socket = 0;
+ cookie->want_socket = want_socket;
+ cookie->fd = -1;
+ log_socket = cookie->fd;
- fp = _gpgrt_fopencookie (cookie, "w", io);
- }
+ io.func_write = fun_writer;
+ io.func_close = fun_closer;
+
+ fp = _gpgrt_fopencookie (cookie, "w", io);
+ }
/* On error default to a stderr based estream. */
if (!fp)
diff --git a/src/mkheader.c b/src/mkheader.c
index 1d2ea20..154d79f 100644
--- a/src/mkheader.c
+++ b/src/mkheader.c
@@ -563,6 +563,13 @@ write_special (const char *fname, int lnr, const char *tag)
else
fputs ("ssize_t", stdout);
}
+ else if (!strcmp (tag, "SOCKET_t"))
+ {
+ if (have_w32_system)
+ fputs ("uintptr_t", stdout);
+ else
+ fputs ("int", stdout);
+ }
else if (!strcmp (tag, "define:pid_t"))
{
if (have_sys_types_h)
diff --git a/src/posix-lock.c b/src/posix-lock.c
index d0fd07a..85ec660 100644
--- a/src/posix-lock.c
+++ b/src/posix-lock.c
@@ -67,6 +67,38 @@
# endif
# endif /*!USE_POSIX_THREADS_WEAK*/
# if PTHREAD_IN_USE_DETECTION_HARD
+# if defined __FreeBSD__ || defined __DragonFly__ /* FreeBSD */
+
+/* Test using pthread_key_create. */
+
+static int
+use_pthread_p (void)
+{
+ static int tested;
+ static int result; /* 1: linked with -lpthread, 0: only with libc */
+
+ if (!tested)
+ {
+ pthread_key_t key;
+ int err = pthread_key_create (&key, NULL);
+
+ if (err == ENOSYS)
+ result = 0;
+ else
+ {
+ result = 1;
+ if (err == 0)
+ pthread_key_delete (key);
+ }
+ tested = 1;
+ }
+ return result;
+}
+
+# else /* Solaris, HP-UX */
+
+/* Test using pthread_create. */
+
/* The function to be executed by a dummy thread. */
static void *
dummy_thread_func (void *arg)
@@ -84,7 +116,7 @@ use_pthread_p (void)
{
pthread_t thread;
- if (pthread_create (&thread, NULL, dummy_thread_func, NULL))
+ if (pthread_create (&thread, NULL, dummy_thread_func, NULL) != 0)
result = 0; /* Thread creation failed. */
else
{
@@ -102,6 +134,8 @@ use_pthread_p (void)
}
return result;
}
+# endif /* Solaris, HP-UX */
+
# endif /*PTHREAD_IN_USE_DETECTION_HARD*/
#endif /*USE_POSIX_THREADS*/
diff --git a/src/spawn-w32.c b/src/spawn-w32.c
index 3ede1f2..1b5f085 100644
--- a/src/spawn-w32.c
+++ b/src/spawn-w32.c
@@ -74,11 +74,14 @@
* long as the range of the value in the type HANDLE can be
* represented by an int, it works.
*
- * FIXME: Breaking ABI for pid_t will be needed when the value won't
- * fit within 32-bit range on 64-bit machine.
+ * FIXME with original MinGW: Breaking ABI for pid_t will be needed
+ * when the value won't fit within 32-bit range on 64-bit machine.
+ *
+ * Note that pid_t is 64-bit integer in sys/types.h with MinGW-w64.
+ * So, no problem with MinGW-w64.
*/
#define pid_to_handle(a) ((HANDLE)(a))
-#define handle_to_pid(a) ((int)(a))
+#define handle_to_pid(a) ((pid_t)(a))
/* Return the maximum number of currently allowed open file
@@ -421,7 +424,7 @@ _gpgrt_spawn_process (const char *pgmname, const char *argv[],
*r_outfp = NULL;
if (r_errfp)
*r_errfp = NULL;
- *pid = (pid_t)(-1); /* Always required. */
+ *pid = (pid_t)INVALID_HANDLE_VALUE; /* Always required. */
if (r_infp)
{
@@ -650,7 +653,7 @@ _gpgrt_spawn_process_fd (const char *pgmname, const char *argv[],
HANDLE stdhd[3];
/* Setup return values. */
- *pid = (pid_t)(-1);
+ *pid = (pid_t)INVALID_HANDLE_VALUE;
/* Prepare security attributes. */
memset (&sec_attr, 0, sizeof sec_attr );
@@ -746,7 +749,7 @@ _gpgrt_wait_processes (const char **pgmnames, pid_t *pids, size_t count,
if (r_exitcodes)
r_exitcodes[i] = -1;
- if (pids[i] == (pid_t)(-1))
+ if (pids[i] == (pid_t)INVALID_HANDLE_VALUE)
return GPG_ERR_INV_VALUE;
procs[i] = pid_to_handle (pids[i]);
@@ -896,7 +899,7 @@ _gpgrt_spawn_process_detached (const char *pgmname, const char *argv[],
void
_gpgrt_kill_process (pid_t pid)
{
- if (pid != (pid_t) INVALID_HANDLE_VALUE)
+ if (pid != (pid_t)INVALID_HANDLE_VALUE)
{
HANDLE process = (HANDLE) pid;
diff --git a/src/w32-estream.c b/src/w32-estream.c
index 5bb1bcf..e17ea2c 100644
--- a/src/w32-estream.c
+++ b/src/w32-estream.c
@@ -39,6 +39,10 @@
#include <io.h>
#include <windows.h>
+#ifndef EOPNOTSUPP
+# define EOPNOTSUPP ENOSYS
+#endif
+
/* Enable tracing. The value is the module name to be printed. */
/*#define ENABLE_TRACING "estream" */