mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
New facility, platform_start_subprocess.
We already have the ability to start a subprocess and hook it up to a Socket, for running local proxy commands. Now the same facility is available as an auxiliary feature, so that a backend can start another subcommand for a different purpose, and make a separate Socket to communicate with it. Just like the local proxy system, this facility captures the subprocess's stderr, and passes it back to the caller via plug_log. To make that not look silly, I had to add a system where the "proxy:" prefix on the usual plug_log messages is reconfigurable, and when you call platform_start_subprocess(), you get to pass the prefix you want to use in this case.
This commit is contained in:
parent
a92aeca111
commit
eec350c38b
@ -397,8 +397,10 @@ void backend_socket_log(Seat *seat, LogContext *logctx,
|
|||||||
typedef struct ProxyStderrBuf {
|
typedef struct ProxyStderrBuf {
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
size_t size;
|
size_t size;
|
||||||
|
const char *prefix; /* must be statically allocated */
|
||||||
} ProxyStderrBuf;
|
} ProxyStderrBuf;
|
||||||
void psb_init(ProxyStderrBuf *psb);
|
void psb_init(ProxyStderrBuf *psb);
|
||||||
|
void psb_set_prefix(ProxyStderrBuf *psb, const char *prefix);
|
||||||
void log_proxy_stderr(
|
void log_proxy_stderr(
|
||||||
Plug *plug, ProxyStderrBuf *psb, const void *vdata, size_t len);
|
Plug *plug, ProxyStderrBuf *psb, const void *vdata, size_t len);
|
||||||
|
|
||||||
@ -429,4 +431,6 @@ struct DeferredSocketOpenerVtable {
|
|||||||
static inline void deferred_socket_opener_free(DeferredSocketOpener *dso)
|
static inline void deferred_socket_opener_free(DeferredSocketOpener *dso)
|
||||||
{ dso->vt->free(dso); }
|
{ dso->vt->free(dso); }
|
||||||
|
|
||||||
|
DeferredSocketOpener *null_deferred_socket_opener(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
10
putty.h
10
putty.h
@ -2893,6 +2893,16 @@ typedef void (*toplevel_callback_notify_fn_t)(void *ctx);
|
|||||||
void request_callback_notifications(toplevel_callback_notify_fn_t notify,
|
void request_callback_notifications(toplevel_callback_notify_fn_t notify,
|
||||||
void *ctx);
|
void *ctx);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Facility provided by the platform to spawn a parallel subprocess
|
||||||
|
* and present its stdio via a Socket.
|
||||||
|
*
|
||||||
|
* 'prefix' indicates the prefix that should appear on messages passed
|
||||||
|
* to plug_log to provide stderr output from the process.
|
||||||
|
*/
|
||||||
|
Socket *platform_start_subprocess(const char *cmd, Plug *plug,
|
||||||
|
const char *prefix);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Define no-op macros for the jump list functions, on platforms that
|
* Define no-op macros for the jump list functions, on platforms that
|
||||||
* don't support them. (This is a bit of a hack, and it'd be nicer to
|
* don't support them. (This is a bit of a hack, and it'd be nicer to
|
||||||
|
@ -26,5 +26,6 @@ add_sources_from_current_dir(utils
|
|||||||
null-cipher.c
|
null-cipher.c
|
||||||
null-key.c
|
null-key.c
|
||||||
null-mac.c
|
null-mac.c
|
||||||
|
null-opener.c
|
||||||
null-plug.c
|
null-plug.c
|
||||||
null-seat.c)
|
null-seat.c)
|
||||||
|
20
stubs/null-opener.c
Normal file
20
stubs/null-opener.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Null implementation of DeferredSocketOpener. Doesn't even bother to
|
||||||
|
* allocate and free itself: there's just one static implementation
|
||||||
|
* which we hand out to any caller.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "putty.h"
|
||||||
|
|
||||||
|
static void null_opener_free(DeferredSocketOpener *opener) {}
|
||||||
|
|
||||||
|
static const DeferredSocketOpenerVtable NullOpener_vt = {
|
||||||
|
.free = null_opener_free,
|
||||||
|
};
|
||||||
|
|
||||||
|
static DeferredSocketOpener null_opener = { .vt = &NullOpener_vt };
|
||||||
|
|
||||||
|
DeferredSocketOpener *null_deferred_socket_opener(void)
|
||||||
|
{
|
||||||
|
return &null_opener;
|
||||||
|
}
|
@ -371,6 +371,13 @@ void setup_fd_socket(Socket *s, int infd, int outfd, int inerrfd)
|
|||||||
queue_toplevel_callback(fdsocket_connect_success_callback, fds);
|
queue_toplevel_callback(fdsocket_connect_success_callback, fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fd_socket_set_psb_prefix(Socket *s, const char *prefix)
|
||||||
|
{
|
||||||
|
FdSocket *fds = container_of(s, FdSocket, sock);
|
||||||
|
assert(fds->sock.vt == &FdSocket_sockvt);
|
||||||
|
psb_set_prefix(&fds->psb, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
static FdSocket *make_fd_socket_internal(SockAddr *addr, int port, Plug *plug)
|
static FdSocket *make_fd_socket_internal(SockAddr *addr, int port, Plug *plug)
|
||||||
{
|
{
|
||||||
FdSocket *fds;
|
FdSocket *fds;
|
||||||
|
@ -96,3 +96,21 @@ Socket *platform_new_connection(SockAddr *addr, const char *hostname,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Socket *platform_start_subprocess(const char *cmd, Plug *plug,
|
||||||
|
const char *prefix)
|
||||||
|
{
|
||||||
|
Socket *socket = make_deferred_fd_socket(
|
||||||
|
null_deferred_socket_opener(),
|
||||||
|
sk_nonamelookup("<local command>"), 0, plug);
|
||||||
|
char *err = platform_setup_local_proxy(socket, cmd);
|
||||||
|
fd_socket_set_psb_prefix(socket, prefix);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
sk_close(socket);
|
||||||
|
socket = new_error_socket_fmt(plug, "%s", err);
|
||||||
|
sfree(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
@ -389,6 +389,7 @@ Socket *make_fd_socket(int infd, int outfd, int inerrfd,
|
|||||||
Socket *make_deferred_fd_socket(DeferredSocketOpener *opener,
|
Socket *make_deferred_fd_socket(DeferredSocketOpener *opener,
|
||||||
SockAddr *addr, int port, Plug *plug);
|
SockAddr *addr, int port, Plug *plug);
|
||||||
void setup_fd_socket(Socket *s, int infd, int outfd, int inerrfd);
|
void setup_fd_socket(Socket *s, int infd, int outfd, int inerrfd);
|
||||||
|
void fd_socket_set_psb_prefix(Socket *s, const char *prefix);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default font setting, which can vary depending on NOT_X_WINDOWS.
|
* Default font setting, which can vary depending on NOT_X_WINDOWS.
|
||||||
|
@ -7,6 +7,12 @@
|
|||||||
void psb_init(ProxyStderrBuf *psb)
|
void psb_init(ProxyStderrBuf *psb)
|
||||||
{
|
{
|
||||||
psb->size = 0;
|
psb->size = 0;
|
||||||
|
psb->prefix = "proxy";
|
||||||
|
}
|
||||||
|
|
||||||
|
void psb_set_prefix(ProxyStderrBuf *psb, const char *prefix)
|
||||||
|
{
|
||||||
|
psb->prefix = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
|
void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
|
||||||
@ -58,7 +64,7 @@ void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
|
|||||||
psb->buf[endpos-1] == '\r'))
|
psb->buf[endpos-1] == '\r'))
|
||||||
endpos--;
|
endpos--;
|
||||||
char *msg = dupprintf(
|
char *msg = dupprintf(
|
||||||
"proxy: %.*s", (int)(endpos - pos), psb->buf + pos);
|
"%s: %.*s", psb->prefix, (int)(endpos - pos), psb->buf + pos);
|
||||||
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
|
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
|
||||||
sfree(msg);
|
sfree(msg);
|
||||||
|
|
||||||
@ -73,7 +79,8 @@ void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
|
|||||||
*/
|
*/
|
||||||
if (pos == 0 && psb->size == lenof(psb->buf)) {
|
if (pos == 0 && psb->size == lenof(psb->buf)) {
|
||||||
char *msg = dupprintf(
|
char *msg = dupprintf(
|
||||||
"proxy (partial line): %.*s", (int)psb->size, psb->buf);
|
"%s (partial line): %.*s", psb->prefix, (int)psb->size,
|
||||||
|
psb->buf);
|
||||||
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
|
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
|
||||||
sfree(msg);
|
sfree(msg);
|
||||||
|
|
||||||
|
@ -388,6 +388,13 @@ Socket *make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
|
|||||||
return &hs->sock;
|
return &hs->sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_socket_set_psb_prefix(Socket *s, const char *prefix)
|
||||||
|
{
|
||||||
|
HandleSocket *hs = container_of(s, HandleSocket, sock);
|
||||||
|
assert(hs->sock.vt == &HandleSocket_sockvt);
|
||||||
|
psb_set_prefix(&hs->psb, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
static void sk_handle_deferred_close(Socket *s)
|
static void sk_handle_deferred_close(Socket *s)
|
||||||
{
|
{
|
||||||
HandleSocket *hs = container_of(s, HandleSocket, sock);
|
HandleSocket *hs = container_of(s, HandleSocket, sock);
|
||||||
|
@ -98,3 +98,21 @@ Socket *platform_new_connection(SockAddr *addr, const char *hostname,
|
|||||||
local_proxy_opener_set_socket(opener, socket);
|
local_proxy_opener_set_socket(opener, socket);
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Socket *platform_start_subprocess(const char *cmd, Plug *plug,
|
||||||
|
const char *prefix)
|
||||||
|
{
|
||||||
|
Socket *socket = make_deferred_handle_socket(
|
||||||
|
null_deferred_socket_opener(),
|
||||||
|
sk_nonamelookup("<local command>"), 0, plug);
|
||||||
|
char *err = platform_setup_local_proxy(socket, cmd);
|
||||||
|
handle_socket_set_psb_prefix(socket, prefix);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
sk_close(socket);
|
||||||
|
socket = new_error_socket_fmt(plug, "%s", err);
|
||||||
|
sfree(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
@ -354,6 +354,7 @@ Socket *make_deferred_handle_socket(DeferredSocketOpener *opener,
|
|||||||
SockAddr *addr, int port, Plug *plug);
|
SockAddr *addr, int port, Plug *plug);
|
||||||
void setup_handle_socket(Socket *s, HANDLE send_H, HANDLE recv_H,
|
void setup_handle_socket(Socket *s, HANDLE send_H, HANDLE recv_H,
|
||||||
HANDLE stderr_H, bool overlapped);
|
HANDLE stderr_H, bool overlapped);
|
||||||
|
void handle_socket_set_psb_prefix(Socket *s, const char *prefix);
|
||||||
Socket *new_named_pipe_client(const char *pipename, Plug *plug); /* winnpc */
|
Socket *new_named_pipe_client(const char *pipename, Plug *plug); /* winnpc */
|
||||||
Socket *new_named_pipe_listener(const char *pipename, Plug *plug); /* winnps */
|
Socket *new_named_pipe_listener(const char *pipename, Plug *plug); /* winnps */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user