From ed9511a5d94229192c2f6b67bdd97900b6575339 Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Thu, 5 Aug 2021 16:03:43 -0400 Subject: [PATCH 1/9] Add functionality to write to a temp file through url arguments --- man/ttyd.1 | 4 ++++ man/ttyd.man.md | 3 +++ src/protocol.c | 27 ++++++++++++++++++++++++--- src/server.c | 14 +++++++++++--- src/server.h | 1 + 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/man/ttyd.1 b/man/ttyd.1 index 000cb45e..bb412edd 100644 --- a/man/ttyd.1 +++ b/man/ttyd.1 @@ -63,6 +63,10 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows Allow client to send command line arguments in URL (eg: \[la]http://localhost:7681?arg=foo&arg=bar\[ra]) +.PP +\-f, \-\-arg\-file + Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument + .PP \-R, \-\-readonly Do not allow clients to write to the TTY diff --git a/man/ttyd.man.md b/man/ttyd.man.md index b90cd97d..1b80179d 100644 --- a/man/ttyd.man.md +++ b/man/ttyd.man.md @@ -40,6 +40,9 @@ ttyd 1 "September 2016" ttyd "User Manual" -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar) + -f, --arg-file + Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument + -R, --readonly Do not allow clients to write to the TTY diff --git a/src/protocol.c b/src/protocol.c index e7255c3c..e693eb05 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -102,9 +102,30 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) for (i = 0; i < server->argc; i++) { argv[n++] = server->argv[i]; } - for (i = 0; i < pss->argc; i++) { - argv[n++] = pss->args[i]; + if (server->url_arg) { + for (i = 0; i < pss->argc; i++) { + argv[n++] = pss->args[i]; + } } + else if (server->arg_file) { + int fd = -1; + char filePath[] = "/tmp/XXXXXX"; + + if ((fd = mkstemp(filePath)) == -1) { + lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); + return false; + } + + for (i = 0; i < pss->argc; i++) { + if (dprintf(fd, "%s\n", pss->args[i]) < 0) { + lwsl_err("Write to temp file failed with error: %d (%s)\n", errno, strerror(errno)); + return false; + } + } + + argv[n++] = filePath; + } + argv[n] = NULL; pty_process *process = process_init((void *) pss, server->loop, argv); @@ -178,7 +199,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, pss->wsi = wsi; pss->lws_close_status = LWS_CLOSE_STATUS_NOSTATUS; - if (server->url_arg) { + if (server->url_arg || server->arg_file) { while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) { if (strncmp(buf, "arg=", 4) == 0) { pss->args = xrealloc(pss->args, (pss->argc + 1) * sizeof(char *)); diff --git a/src/server.c b/src/server.c index d842f392..ce8493f4 100644 --- a/src/server.c +++ b/src/server.c @@ -73,6 +73,7 @@ static const struct option options[] = { {"ssl-key", required_argument, NULL, 'K'}, {"ssl-ca", required_argument, NULL, 'A'}, {"url-arg", no_argument, NULL, 'a'}, + {"arg-file", no_argument, NULL, 'f'}, {"readonly", no_argument, NULL, 'R'}, {"terminal-type", required_argument, NULL, 'T'}, {"client-option", required_argument, NULL, 't'}, @@ -86,10 +87,10 @@ static const struct option options[] = { {NULL, 0, 0, 0}}; #if LWS_LIBRARY_VERSION_NUMBER < 4000000 -static const char *opt_string = "p:i:c:u:g:s:I:b:6aSC:K:A:Rt:T:Om:oBd:vh"; +static const char *opt_string = "p:i:c:u:g:s:I:b:6afSC:K:A:Rt:T:Om:oBd:vh"; #endif #if LWS_LIBRARY_VERSION_NUMBER >= 4000000 -static const char *opt_string = "p:i:c:u:g:s:I:b:P:6aSC:K:A:Rt:T:Om:oBd:vh"; +static const char *opt_string = "p:i:c:u:g:s:I:b:P:6afSC:K:A:Rt:T:Om:oBd:vh"; #endif static void print_help() { @@ -107,6 +108,7 @@ static void print_help() { " -g, --gid Group id to run with\n" " -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP)\n" " -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)\n" + " -f, --arg-file Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument\n" " -R, --readonly Do not allow clients to write to the TTY\n" " -t, --client-option Send option to client (format: key=value), repeat to add more options\n" " -T, --terminal-type Terminal type to report, default: xterm-256color\n" @@ -321,6 +323,11 @@ int main(int argc, char **argv) { break; case 'a': server->url_arg = true; + server->arg_file = false; + break; + case 'f': + server->arg_file = true; + server->url_arg = false; break; case 'R': server->readonly = true; @@ -537,7 +544,8 @@ int main(int argc, char **argv) { lwsl_notice(" websocket: %s\n", endpoints.ws); } if (server->check_origin) lwsl_notice(" check origin: true\n"); - if (server->url_arg) lwsl_notice(" allow url arg: true\n"); + if (server->url_arg) lwsl_notice(" allow url arg to cli arg: true\n"); + if (server->arg_file) lwsl_notice(" allow url arg to tmp file: true\n"); if (server->readonly) lwsl_notice(" readonly: true\n"); if (server->max_clients > 0) lwsl_notice(" max clients: %d\n", server->max_clients); diff --git a/src/server.h b/src/server.h index 8fc5dde1..e014db23 100644 --- a/src/server.h +++ b/src/server.h @@ -65,6 +65,7 @@ struct server { int sig_code; // close signal char sig_name[20]; // human readable signal string bool url_arg; // allow client to send cli arguments in URL + bool arg_file; // allow client to write to a temp file through URL arguments bool readonly; // whether not allow clients to write to the TTY bool check_origin; // whether allow websocket connection from different origin int max_clients; // maximum clients to support From cde09827ac7450a34c9682806f2427c6c4b7ba42 Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Fri, 6 Aug 2021 12:09:17 -0400 Subject: [PATCH 2/9] close file --- src/protocol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/protocol.c b/src/protocol.c index e693eb05..b3c5a9c2 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -124,6 +124,7 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) } argv[n++] = filePath; + close(fd); } argv[n] = NULL; From 25f91ea51c98eb2bcc27a1ef5ce2b19901620bee Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Fri, 6 Aug 2021 12:27:44 -0400 Subject: [PATCH 3/9] Add argument for temp file path/prefix --- README.md | 1 + man/ttyd.1 | 3 +-- man/ttyd.man.md | 2 +- src/protocol.c | 6 +++--- src/server.c | 15 ++++++++------- src/server.h | 2 +- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bdcd1fc4..c37783ac 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ OPTIONS: -g, --gid Group id to run with -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP) -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar) + -f, --arg-file File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}) -R, --readonly Do not allow clients to write to the TTY -t, --client-option Send option to client (format: key=value), repeat to add more options -T, --terminal-type Terminal type to report, default: xterm-256color diff --git a/man/ttyd.1 b/man/ttyd.1 index bb412edd..b2f02aae 100644 --- a/man/ttyd.1 +++ b/man/ttyd.1 @@ -65,8 +65,7 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows .PP \-f, \-\-arg\-file - Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument - + File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}) .PP \-R, \-\-readonly Do not allow clients to write to the TTY diff --git a/man/ttyd.man.md b/man/ttyd.man.md index 1b80179d..28953608 100644 --- a/man/ttyd.man.md +++ b/man/ttyd.man.md @@ -41,7 +41,7 @@ ttyd 1 "September 2016" ttyd "User Manual" Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar) -f, --arg-file - Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument + File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}) -R, --readonly Do not allow clients to write to the TTY diff --git a/src/protocol.c b/src/protocol.c index b3c5a9c2..fbdd365d 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -107,9 +107,9 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) argv[n++] = pss->args[i]; } } - else if (server->arg_file) { + else if (server->arg_file != NULL) { int fd = -1; - char filePath[] = "/tmp/XXXXXX"; + char *filePath = strcat(server->arg_file, "XXXXXX"); if ((fd = mkstemp(filePath)) == -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); @@ -200,7 +200,7 @@ int callback_tty(struct lws *wsi, enum lws_callback_reasons reason, void *user, pss->wsi = wsi; pss->lws_close_status = LWS_CLOSE_STATUS_NOSTATUS; - if (server->url_arg || server->arg_file) { + if (server->url_arg || server->arg_file != NULL) { while (lws_hdr_copy_fragment(wsi, buf, sizeof(buf), WSI_TOKEN_HTTP_URI_ARGS, n++) > 0) { if (strncmp(buf, "arg=", 4) == 0) { pss->args = xrealloc(pss->args, (pss->argc + 1) * sizeof(char *)); diff --git a/src/server.c b/src/server.c index ce8493f4..d69f046c 100644 --- a/src/server.c +++ b/src/server.c @@ -73,7 +73,7 @@ static const struct option options[] = { {"ssl-key", required_argument, NULL, 'K'}, {"ssl-ca", required_argument, NULL, 'A'}, {"url-arg", no_argument, NULL, 'a'}, - {"arg-file", no_argument, NULL, 'f'}, + {"arg-file", required_argument, NULL, 'f'}, {"readonly", no_argument, NULL, 'R'}, {"terminal-type", required_argument, NULL, 'T'}, {"client-option", required_argument, NULL, 't'}, @@ -87,10 +87,10 @@ static const struct option options[] = { {NULL, 0, 0, 0}}; #if LWS_LIBRARY_VERSION_NUMBER < 4000000 -static const char *opt_string = "p:i:c:u:g:s:I:b:6afSC:K:A:Rt:T:Om:oBd:vh"; +static const char *opt_string = "p:i:c:u:g:s:I:b:6af:SC:K:A:Rt:T:Om:oBd:vh"; #endif #if LWS_LIBRARY_VERSION_NUMBER >= 4000000 -static const char *opt_string = "p:i:c:u:g:s:I:b:P:6afSC:K:A:Rt:T:Om:oBd:vh"; +static const char *opt_string = "p:i:c:u:g:s:I:b:P:6af:SC:K:A:Rt:T:Om:oBd:vh"; #endif static void print_help() { @@ -108,7 +108,7 @@ static void print_help() { " -g, --gid Group id to run with\n" " -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP)\n" " -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)\n" - " -f, --arg-file Allow client to write URL arguments to a temporary file; the file name is then passed in as a command line argument\n" + " -f, --arg-file File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string})\n" " -R, --readonly Do not allow clients to write to the TTY\n" " -t, --client-option Send option to client (format: key=value), repeat to add more options\n" " -T, --terminal-type Terminal type to report, default: xterm-256color\n" @@ -184,6 +184,7 @@ static struct server *server_new(int argc, char **argv, int start) { static void server_free(struct server *ts) { if (ts == NULL) return; + if (ts->arg_file != NULL) free(ts->arg_file); if (ts->credential != NULL) free(ts->credential); if (ts->index != NULL) free(ts->index); free(ts->command); @@ -323,10 +324,10 @@ int main(int argc, char **argv) { break; case 'a': server->url_arg = true; - server->arg_file = false; + server->arg_file = NULL; break; case 'f': - server->arg_file = true; + server->arg_file = strdup(optarg); server->url_arg = false; break; case 'R': @@ -545,7 +546,7 @@ int main(int argc, char **argv) { } if (server->check_origin) lwsl_notice(" check origin: true\n"); if (server->url_arg) lwsl_notice(" allow url arg to cli arg: true\n"); - if (server->arg_file) lwsl_notice(" allow url arg to tmp file: true\n"); + if (server->arg_file != NULL) lwsl_notice(" temp file name prefix: %s\n", server->arg_file); if (server->readonly) lwsl_notice(" readonly: true\n"); if (server->max_clients > 0) lwsl_notice(" max clients: %d\n", server->max_clients); diff --git a/src/server.h b/src/server.h index e014db23..bc1ee7bb 100644 --- a/src/server.h +++ b/src/server.h @@ -65,7 +65,7 @@ struct server { int sig_code; // close signal char sig_name[20]; // human readable signal string bool url_arg; // allow client to send cli arguments in URL - bool arg_file; // allow client to write to a temp file through URL arguments + char *arg_file; // file prefix for a generated temp file that URL arguments are written to bool readonly; // whether not allow clients to write to the TTY bool check_origin; // whether allow websocket connection from different origin int max_clients; // maximum clients to support From 53565c7262f128705a962b5a9ba3cc3dc0526a74 Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Mon, 9 Aug 2021 13:28:32 -0400 Subject: [PATCH 4/9] Concat temp file suffix without strcat --- src/protocol.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/protocol.c b/src/protocol.c index fbdd365d..b80dfcf0 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -109,7 +109,8 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) } else if (server->arg_file != NULL) { int fd = -1; - char *filePath = strcat(server->arg_file, "XXXXXX"); + char *filePath = xmalloc(strlen(server->arg_file) + 7); + sprintf(filePath, "%sXXXXXX", server->arg_file); if ((fd = mkstemp(filePath)) == -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); From 5a3ad2ff5bace7415043f104b6b3c28d14c744a8 Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Mon, 9 Aug 2021 14:08:01 -0400 Subject: [PATCH 5/9] use snprintf instead of sprintf --- src/protocol.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/protocol.c b/src/protocol.c index b80dfcf0..eb69b0b3 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -109,8 +109,10 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) } else if (server->arg_file != NULL) { int fd = -1; - char *filePath = xmalloc(strlen(server->arg_file) + 7); - sprintf(filePath, "%sXXXXXX", server->arg_file); + // mkstemp requires the file path to have suffix XXXXXX (len 7) + int file_path_len = strlen(server->arg_file) + 7; + char *filePath = xmalloc(file_path_len); + snprintf(filePath, file_path_len, "%sXXXXXX", server->arg_file); if ((fd = mkstemp(filePath)) == -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); From 4be50095c15c4368422eeef82921f481edb9dbac Mon Sep 17 00:00:00 2001 From: Vaishali Kumanan Date: Mon, 16 Aug 2021 12:50:53 -0400 Subject: [PATCH 6/9] Reformat code --- src/protocol.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/protocol.c b/src/protocol.c index eb69b0b3..bbfa1f3e 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -106,15 +106,13 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) for (i = 0; i < pss->argc; i++) { argv[n++] = pss->args[i]; } - } - else if (server->arg_file != NULL) { + } else if (server->arg_file != NULL) { int fd = -1; - // mkstemp requires the file path to have suffix XXXXXX (len 7) - int file_path_len = strlen(server->arg_file) + 7; + int file_path_len = strlen(server->arg_file) + 6 /*XXXXXX*/ + 1 /*null character*/; char *filePath = xmalloc(file_path_len); snprintf(filePath, file_path_len, "%sXXXXXX", server->arg_file); - if ((fd = mkstemp(filePath)) == -1) { + if ((fd = mkstemp(filePath)) != -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); return false; } @@ -126,8 +124,11 @@ static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) } } + if (close(fd) != 0) { + lwsl_err("Close temp file failed with error: %d (%s)\n", errno, strerror(errno)); + return false + } argv[n++] = filePath; - close(fd); } argv[n] = NULL; From 092dc3d13179348db48bd10fc5b655a50f1e0c8b Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Fri, 27 Aug 2021 16:09:57 -0700 Subject: [PATCH 7/9] fix build and error check --- src/protocol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/protocol.c b/src/protocol.c index c2f8f08f..1406e394 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -111,7 +111,7 @@ static char **build_args(struct pss_tty *pss) { char *filePath = xmalloc(file_path_len); snprintf(filePath, file_path_len, "%sXXXXXX", server->arg_file); - if ((fd = mkstemp(filePath)) != -1) { + if ((fd = mkstemp(filePath)) == -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); return false; } @@ -125,7 +125,7 @@ static char **build_args(struct pss_tty *pss) { if (close(fd) != 0) { lwsl_err("Close temp file failed with error: %d (%s)\n", errno, strerror(errno)); - return false + return false; } argv[n++] = filePath; } From b9b962b4eab667f87bc32e8938849e90ff88bbb0 Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Mon, 30 Aug 2021 13:42:17 -0700 Subject: [PATCH 8/9] fix a merge problem and addressed feedback --- src/protocol.c | 4 ++++ src/server.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/protocol.c b/src/protocol.c index 1406e394..1a5d7bee 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -113,18 +113,22 @@ static char **build_args(struct pss_tty *pss) { if ((fd = mkstemp(filePath)) == -1) { lwsl_err("Creation of temp file failed with error: %d (%s)\n", errno, strerror(errno)); + free(filePath); return false; } for (i = 0; i < pss->argc; i++) { if (dprintf(fd, "%s\n", pss->args[i]) < 0) { lwsl_err("Write to temp file failed with error: %d (%s)\n", errno, strerror(errno)); + close(fd); + free(filePath); return false; } } if (close(fd) != 0) { lwsl_err("Close temp file failed with error: %d (%s)\n", errno, strerror(errno)); + free(filePath); return false; } argv[n++] = filePath; diff --git a/src/server.c b/src/server.c index df38f3b2..54d9e2a1 100644 --- a/src/server.c +++ b/src/server.c @@ -82,7 +82,7 @@ static const struct option options[] = {{"port", required_argument, NULL, 'p'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, 0, 0}}; -static const char *opt_string = "p:i:c:H:u:g:s:w:I:b:P:6aSC:K:A:Rt:T:Om:oBd:vh"; +static const char *opt_string = "p:i:c:H:u:g:s:w:I:b:P:6af:SC:K:A:Rt:T:Om:oBd:vh"; static void print_help() { // clang-format off From c01676c8585cd2520fa36c87a5baa7ca7c55ae79 Mon Sep 17 00:00:00 2001 From: Ka-Hing Cheung Date: Thu, 2 Sep 2021 12:43:56 -0700 Subject: [PATCH 9/9] add a note to -f --- man/ttyd.1 | 2 +- man/ttyd.man.md | 2 +- src/server.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/man/ttyd.1 b/man/ttyd.1 index 863bccb7..0f124515 100644 --- a/man/ttyd.1 +++ b/man/ttyd.1 @@ -73,7 +73,7 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows .PP \-f, \-\-arg\-file - File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}) + File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}). The command is responsible for deleting the file. .PP \-R, \-\-readonly Do not allow clients to write to the TTY diff --git a/man/ttyd.man.md b/man/ttyd.man.md index d7d09937..b09a2a11 100644 --- a/man/ttyd.man.md +++ b/man/ttyd.man.md @@ -47,7 +47,7 @@ ttyd 1 "September 2016" ttyd "User Manual" Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar) -f, --arg-file - File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}) + File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}). The command is responsible for deleting the file. -R, --readonly Do not allow clients to write to the TTY diff --git a/src/server.c b/src/server.c index 54d9e2a1..1f1d01b7 100644 --- a/src/server.c +++ b/src/server.c @@ -101,7 +101,7 @@ static void print_help() { " -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP)\n" " -w, --cwd Working directory to be set for the child program\n" " -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar)\n" - " -f, --arg-file File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string})\n" + " -f, --arg-file File prefix for a unique generated temp file that URL arguments are written to (ex. /tmp/prefix); the generated file's full path is then passed in as a command line argument (ex. /tmp/prefix{unique string}). The command is responsible for deleting the file.\n" " -R, --readonly Do not allow clients to write to the TTY\n" " -t, --client-option Send option to client (format: key=value), repeat to add more options\n" " -T, --terminal-type Terminal type to report, default: xterm-256color\n"