diff options
author | Werner Koch <wk@gnupg.org> | 2022-04-07 10:44:11 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2022-04-07 10:44:11 +0200 |
commit | ff3b2ea8858a7f95633edf0d41d1815048aa8ac8 (patch) | |
tree | d7112ccf738440cc87541952068e917e272afb18 | |
parent | 038d34656f5b4f0075eced12e86e983163d6d881 (diff) | |
parent | 74e6afcc36b28b0acc49fbe25f29b42d1a223caf (diff) | |
download | libgpg-error-ff3b2ea8858a7f95633edf0d41d1815048aa8ac8.tar.gz |
Merge branch 'master' of ssh+git://playfair.gnupg.org/git/libgpg-error
--
-rw-r--r-- | doc/yat2m.c | 3 | ||||
-rw-r--r-- | src/estream.c | 256 | ||||
-rw-r--r-- | src/gpg-error.h.in | 2 | ||||
-rw-r--r-- | src/gpgrt-int.h | 1 | ||||
-rw-r--r-- | src/logging.c | 89 | ||||
-rw-r--r-- | src/mkheader.c | 7 | ||||
-rw-r--r-- | src/posix-lock.c | 36 | ||||
-rw-r--r-- | src/spawn-w32.c | 17 | ||||
-rw-r--r-- | src/w32-estream.c | 4 |
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" */ |