From: Shuanglei Tao Date: Mon, 16 Aug 2021 15:08:05 +0000 (+0800) Subject: server: add cwd support X-Git-Url: http://git.prime8.dev/?a=commitdiff_plain;h=bff3a617e6989a656626b71b8a1eff8c1718fb8a;p=ttyd.git server: add cwd support --- diff --git a/man/ttyd.1 b/man/ttyd.1 index 2a7ec97..c4e76ee 100644 --- a/man/ttyd.1 +++ b/man/ttyd.1 @@ -62,6 +62,10 @@ Cross platform: macOS, Linux, FreeBSD/OpenBSD, OpenWrt/LEDE, Windows \-s, \-\-signal Signal to send to the command when exit it (default: 1, SIGHUP) +.PP +\-w, \-\-cwd + Working directory to be set for the child program + .PP \-a, \-\-url\-arg Allow client to send command line arguments in URL (eg: diff --git a/man/ttyd.man.md b/man/ttyd.man.md index baf8fb4..99c3994 100644 --- a/man/ttyd.man.md +++ b/man/ttyd.man.md @@ -40,6 +40,9 @@ ttyd 1 "September 2016" ttyd "User Manual" -s, --signal Signal to send to the command when exit it (default: 1, SIGHUP) + -w, --cwd + Working directory to be set for the child program + -a, --url-arg Allow client to send command line arguments in URL (eg: http://localhost:7681?arg=foo&arg=bar) diff --git a/src/protocol.c b/src/protocol.c index 0cecd26..ca1e086 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -134,6 +134,7 @@ static char **build_env(struct pss_tty *pss) { static bool spawn_process(struct pss_tty *pss, uint16_t columns, uint16_t rows) { pty_process *process = process_init((void *)pss, server->loop, build_args(pss), build_env(pss)); + if (server->cwd != NULL) process->cwd = strdup(server->cwd); if (columns > 0) process->columns = columns; if (rows > 0) process->rows = rows; if (pty_spawn(process, process_read_cb, process_exit_cb) != 0) { diff --git a/src/pty.c b/src/pty.c index 8171ac5..dd10bfd 100644 --- a/src/pty.c +++ b/src/pty.c @@ -125,6 +125,7 @@ void process_free(pty_process *process) { #endif if (process->io != NULL) pty_io_free(process->io); if (process->argv != NULL) free(process->argv); + if (process->cwd != NULL) free(process->cwd); char **p = process->envp; for (; *p; p++) free(*p); free(process->envp); @@ -366,7 +367,7 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) { env = prep_env(process->envp); if (env == NULL) goto cleanup; - if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, flags, env, NULL, &process->si.StartupInfo, &pi)) { + if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, flags, env, process->cwd, &process->si.StartupInfo, &pi)) { print_error("CreateProcessW"); goto cleanup; } @@ -461,6 +462,12 @@ int pty_spawn(pty_process *process, pty_read_cb read_cb, pty_exit_cb exit_cb) { return status; } else if (pid == 0) { setsid(); + if (process->cwd != NULL) { + if (chdir(process->cwd) == -1) { + perror("chdir failed\n"); + _exit(1); + } + } int ret = pty_execvpe(process->argv[0], process->argv, process->envp); if (ret < 0) { perror("execvp failed\n"); diff --git a/src/pty.h b/src/pty.h index c4de47b..dbe5a30 100644 --- a/src/pty.h +++ b/src/pty.h @@ -51,6 +51,7 @@ struct pty_process_ { #endif char **argv; char **envp; + char *cwd; uv_loop_t *loop; uv_async_t async; diff --git a/src/server.c b/src/server.c index f5b985b..f9113af 100644 --- a/src/server.c +++ b/src/server.c @@ -58,6 +58,7 @@ static const struct option options[] = {{"port", required_argument, NULL, 'p'}, {"uid", required_argument, NULL, 'u'}, {"gid", required_argument, NULL, 'g'}, {"signal", required_argument, NULL, 's'}, + {"cwd", required_argument, NULL, 'w'}, {"index", required_argument, NULL, 'I'}, {"base-path", required_argument, NULL, 'b'}, #if LWS_LIBRARY_VERSION_NUMBER >= 4000000 @@ -80,7 +81,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: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:6aSC:K:A:Rt:T:Om:oBd:vh"; static void print_help() { // clang-format off @@ -97,6 +98,7 @@ static void print_help() { " -u, --uid User id to run with\n" " -g, --gid Group id to run with\n" " -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" " -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" @@ -198,6 +200,7 @@ static void server_free(struct server *ts) { if (ts->credential != NULL) free(ts->credential); if (ts->auth_header != NULL) free(ts->auth_header); if (ts->index != NULL) free(ts->index); + if (ts->cwd != NULL) free(ts->cwd); free(ts->command); free(ts->prefs_json); @@ -398,6 +401,9 @@ int main(int argc, char **argv) { return -1; } } break; + case 'w': + server->cwd = strdup(optarg); + break; case 'I': if (!strncmp(optarg, "~/", 2)) { const char *home = getenv("HOME"); diff --git a/src/server.h b/src/server.h index b337536..b122d1c 100644 --- a/src/server.h +++ b/src/server.h @@ -65,6 +65,7 @@ struct server { char *command; // full command line char **argv; // command with arguments int argc; // command + arguments count + char *cwd; // working directory int sig_code; // close signal char sig_name[20]; // human readable signal string bool url_arg; // allow client to send cli arguments in URL