From a1f480468a3b41f3843833654c0b56c33552519c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 7 Nov 2022 11:46:35 +0900 Subject: w32: Support fd passing through pipe. * src/assuan-pipe-connect.c (initial_handshake): Get peer's PID from the initial interaction. * src/assuan-pipe-server.c (assuan_init_pipe_server): Handle the case of FILEDES == NULL on Windows. * tests/Makefile.am [HAVE_W32_SYSTEM] (TESTS): Add fdpassing. * tests/fdpassing.c: Remove including sys/socket.h and sys/wait.h. (cmd_echo): Output to stder, as stdout is /dev/null. (main): Support Windows. -- GnuPG-bug-id: 6236 Signed-off-by: NIIBE Yutaka --- src/assuan-pipe-connect.c | 26 +++++++++++++++++++++++++- src/assuan-pipe-server.c | 12 ++++++++++-- tests/Makefile.am | 4 ++-- tests/fdpassing.c | 34 +++++++++++++++++++++------------- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index 13ea3de..fc56334 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -104,7 +104,31 @@ initial_handshake (assuan_context_t ctx) if (err) TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx, "can't connect server: %s", gpg_strerror (err)); - else if (response != ASSUAN_RESPONSE_OK) + else if (response == ASSUAN_RESPONSE_OK) + { +#ifdef HAVE_W32_SYSTEM + const char *line = ctx->inbound.line + off; + int pid = ASSUAN_INVALID_PID; + + /* Parse the message: OK ..., process %i */ + line = strchr (line, ','); + if (line) + { + line = strchr (line + 1, ' '); + if (line) + { + line = strchr (line + 1, ' '); + if (line) + pid = atoi (line + 1); + } + } + if (pid != ASSUAN_INVALID_PID) + ctx->pid = pid; +#else + ; +#endif + } + else { TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx, "can't connect server: `%s'", ctx->inbound.line); diff --git a/src/assuan-pipe-server.c b/src/assuan-pipe-server.c index 8da54ad..5c960a6 100644 --- a/src/assuan-pipe-server.c +++ b/src/assuan-pipe-server.c @@ -82,8 +82,16 @@ assuan_init_pipe_server (assuan_context_t ctx, assuan_fd_t filedes[2]) return TRACE_ERR (rc); #ifdef HAVE_W32_SYSTEM - infd = filedes[0]; - outfd = filedes[1]; + if (filedes) + { + infd = filedes[0]; + outfd = filedes[1]; + } + else + { + infd = assuan_fd_from_posix_fd (0); + outfd = assuan_fd_from_posix_fd (1); + } #else s = getenv ("_assuan_connection_fd"); if (s && *s && is_valid_socket (s)) diff --git a/tests/Makefile.am b/tests/Makefile.am index f43c712..317c66d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,6 +28,7 @@ CLEANFILES = TESTS = version if HAVE_W32_SYSTEM +TESTS += fdpassing testtools = else TESTS += pipeconnect @@ -43,5 +44,4 @@ AM_LDFLAGS = -no-install noinst_HEADERS = common.h noinst_PROGRAMS = $(TESTS) $(w32cetools) $(testtools) -LDADD = ../src/libassuan.la $(GPG_ERROR_LIBS) \ - @LDADD_FOR_TESTS_KLUDGE@ +LDADD = ../src/libassuan.la $(GPG_ERROR_LIBS) @LDADD_FOR_TESTS_KLUDGE@ diff --git a/tests/fdpassing.c b/tests/fdpassing.c index 0e23ffc..9e1b6e9 100644 --- a/tests/fdpassing.c +++ b/tests/fdpassing.c @@ -25,10 +25,8 @@ #include #include #include -#include #include #include -#include /* Used by main driver. */ #include "../src/assuan.h" #include "common.h" @@ -50,7 +48,7 @@ cmd_echo (assuan_context_t ctx, char *line) log_info ("got ECHO command (%s)\n", line); - fd = assuan_get_input_fd (ctx); + fd = (int)assuan_get_input_fd (ctx); if (fd == -1) return gpg_error (GPG_ERR_ASS_NO_INPUT); fp = fdopen (fd, "r"); @@ -62,11 +60,11 @@ cmd_echo (assuan_context_t ctx, char *line) nbytes = 0; while ( (c=getc (fp)) != -1) { - putc (c, stdout); + putc (c, stderr); nbytes++; } - fflush (stdout); - log_info ("done printing %d bytes to stdout\n", nbytes); + fflush (stderr); + log_info ("done printing %d bytes to stderr\n", nbytes); fclose (fp); return 0; @@ -173,7 +171,7 @@ client (assuan_context_t ctx, const char *fname) return -1; } - rc = assuan_sendfd (ctx, fileno (fp)); + rc = assuan_sendfd (ctx, (assuan_fd_t)fileno (fp)); if (rc) { fclose (fp); @@ -219,7 +217,7 @@ main (int argc, char **argv) int last_argc = -1; assuan_context_t ctx; gpg_error_t err; - int no_close_fds[2]; + assuan_fd_t no_close_fds[2]; const char *arglist[10]; int is_server = 0; int with_exec = 0; @@ -240,7 +238,7 @@ main (int argc, char **argv) "\n" "Options:\n" " --verbose Show what is going on\n" -" --with-exec Exec the child. Default is just a fork\n" +" --with-exec Exec the child. Default is just a fork on POSIX machine\n" ); exit (0); } @@ -266,6 +264,9 @@ main (int argc, char **argv) } } +#ifdef HAVE_W32_SYSTEM + with_exec = 1; +#endif assuan_set_assuan_log_prefix (log_prefix); @@ -277,12 +278,19 @@ main (int argc, char **argv) else { const char *loc; + const char *program_name; + +#ifdef HAVE_W32_SYSTEM + program_name = "fdpassing.exe"; +#else + program_name = "fdpassing"; +#endif - no_close_fds[0] = 2; - no_close_fds[1] = -1; + no_close_fds[0] = verbose? assuan_fd_from_posix_fd (2): (assuan_fd_t)-1; + no_close_fds[1] = (assuan_fd_t)-1; if (with_exec) { - arglist[0] = "fdpassing"; + arglist[0] = program_name; arglist[1] = "--server"; arglist[2] = verbose? "--verbose":NULL; arglist[3] = NULL; @@ -292,7 +300,7 @@ main (int argc, char **argv) if (err) log_fatal ("assuan_new failed: %s\n", gpg_strerror (err)); - err = assuan_pipe_connect (ctx, with_exec? "./fdpassing":NULL, + err = assuan_pipe_connect (ctx, with_exec? program_name : NULL, with_exec ? arglist : &loc, no_close_fds, NULL, NULL, 1); if (err) -- cgit v1.2.1