Skip to content

Commit

Permalink
Start the user's configured shell, use -shellname as argv[0]
Browse files Browse the repository at this point in the history
 * When no command is specified, default to login-mode with the getpwuid()
   shell.

 * Otherwise, allow the -l / --no-login options to override login-mode.

 * Default to pty-mode iff login-mode.
  • Loading branch information
rprichard committed Feb 26, 2018
1 parent b8f4055 commit 34ec0e4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
32 changes: 28 additions & 4 deletions backend/wslbridge-backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <netinet/tcp.h>
#include <pthread.h>
#include <pty.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdint.h>
Expand Down Expand Up @@ -67,6 +68,7 @@ struct ChildParams {
int cols = -1;
int rows = -1;
std::vector<char*> env;
std::string prog;
std::vector<char*> argv;
std::string cwd;
};
Expand Down Expand Up @@ -200,7 +202,7 @@ static Child spawnChild(const ChildParams &params) {
childFailed(SpawnError::Type::ChdirFailed, errno);
}
}
execvp(params.argv[0], params.argv.data());
execvp(params.prog.c_str(), params.argv.data());
childFailed(SpawnError::Type::ExecFailed, errno);
}

Expand Down Expand Up @@ -508,6 +510,7 @@ int main(int argc, char *argv[]) {
int windowThreshold = -1;
ChildParams childParams;
int ptyMode = -1;
bool loginMode = false;

const struct option kOptionTable[] = {
{ "pty", false, &ptyMode, 1 },
Expand All @@ -520,7 +523,7 @@ int main(int argc, char *argv[]) {
};

int ch = 0;
while ((ch = getopt_long(argc, argv, "+3:0:1:2:k:c:r:w:t:e:C:", kOptionTable, nullptr)) != -1) {
while ((ch = getopt_long(argc, argv, "+3:0:1:2:k:c:r:w:t:e:C:l", kOptionTable, nullptr)) != -1) {
switch (ch) {
case 0:
// This is returned for the two long options. getopt_long
Expand All @@ -537,6 +540,7 @@ int main(int argc, char *argv[]) {
case 't': windowThreshold = atoi(optarg); break;
case 'e': childParams.env.push_back(strdup(optarg)); break;
case 'C': childParams.cwd = optarg; break;
case 'l': loginMode = true; break;
case 'v':
printf("wslbridge-backend " STRINGIFY(WSLBRIDGE_VERSION) "\n");
exit(0);
Expand All @@ -548,7 +552,27 @@ int main(int argc, char *argv[]) {
childParams.argv.push_back(argv[i]);
}
if (childParams.argv.empty()) {
fatal("error: no command line given\n");
const char *shell = "/bin/sh";
struct passwd *pw = getpwuid(getuid());
if (pw == nullptr) {
perror("error: getpwuid failed");
} else if (pw->pw_shell == nullptr) {
fprintf(stderr, "error: getpwuid(...)->pw_shell is NULL\n");
} else {
shell = pw->pw_shell;
}
childParams.argv.push_back(strdup(shell));
}
// XXX: Replace char* args/envstrings with std::string?
childParams.prog = childParams.argv[0];
if (loginMode) {
std::string argv0 = childParams.argv[0];
const auto pos = argv0.find_last_of('/');
if (pos != std::string::npos) {
argv0 = argv0.substr(pos + 1);
}
argv0 = '-' + argv0;
childParams.argv[0] = strdup(argv0.c_str());
}
childParams.argv.push_back(nullptr);

Expand Down Expand Up @@ -598,7 +622,7 @@ int main(int argc, char *argv[]) {

mainLoop(childParams.usePty, controlSocket,
inputSocket, outputSocket, errorSocket,
childParams.argv[0], child, windowParams);
childParams.prog.c_str(), child, windowParams);

return 0;
}
33 changes: 23 additions & 10 deletions frontend/wslbridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,8 @@ static void usage(const char *prog) {
printf(" An initial '~' indicates the WSL home directory.\n");
printf(" -e VAR Copies VAR into the WSL environment.\n");
printf(" -e VAR=VAL Sets VAR to VAL in the WSL environment.\n");
printf(" -l Start a login shell.\n");
printf(" --no-login Do not start a login shell.\n");
printf(" -T Do not use a pty.\n");
printf(" -t Use a pty (as long as stdin is a tty).\n");
printf(" -t -t Force a pty (even if stdin is not a tty).\n");
Expand Down Expand Up @@ -982,17 +984,22 @@ int main(int argc, char *argv[]) {
std::string spawnCwd;
std::string distroGuid;
enum class TtyRequest { Auto, Yes, No, Force } ttyRequest = TtyRequest::Auto;
enum class LoginMode { Auto, Yes, No } loginMode = LoginMode::Auto;

int debugFork = 0;
int c = 0;
if (argv[0][0] == '-') {
loginMode = LoginMode::Yes;
}
const struct option kOptionTable[] = {
{ "help", false, nullptr, 'h' },
{ "debug-fork", false, &debugFork, 1 },
{ "version", false, nullptr, 'v' },
{ "distro-guid", true, nullptr, 'd' },
{ "no-login", false, nullptr, 'L' },
{ nullptr, false, nullptr, 0 },
};
while ((c = getopt_long(argc, argv, "+e:C:tT", kOptionTable, nullptr)) != -1) {
while ((c = getopt_long(argc, argv, "+e:C:tTl", kOptionTable, nullptr)) != -1) {
switch (c) {
case 0:
// Ignore long option.
Expand Down Expand Up @@ -1038,14 +1045,23 @@ int main(int argc, char *argv[]) {
fatal("error: the --distro-guid argument '%s' is invalid\n", optarg);
}
break;
case 'l':
loginMode = LoginMode::Yes;
break;
case 'L':
loginMode = LoginMode::No;
break;
default:
fatal("Try '%s --help' for more information.\n", argv[0]);
}
}

const bool hasCommand = optind < argc;
if (loginMode == LoginMode::Auto) {
loginMode = hasCommand ? LoginMode::No : LoginMode::Yes;
}
if (ttyRequest == TtyRequest::Auto) {
ttyRequest = hasCommand ? TtyRequest::No : TtyRequest::Yes;
ttyRequest = loginMode == LoginMode::No ? TtyRequest::No : TtyRequest::Yes;
}
if (ttyRequest == TtyRequest::Yes && !isatty(STDIN_FILENO)) {
fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n");
Expand Down Expand Up @@ -1126,21 +1142,18 @@ int main(int argc, char *argv[]) {
assert(iRet > 0);
bashCmdLine.append(buffer.data());

if (loginMode == LoginMode::Yes) {
appendBashArg(bashCmdLine, L"-l");
}
for (const auto &envPair : env.pairs()) {
appendBashArg(bashCmdLine, L"-e" + envPair.first + L"=" + envPair.second);
}
if (!spawnCwd.empty()) {
appendBashArg(bashCmdLine, L"-C" + mbsToWcs(spawnCwd));
}
appendBashArg(bashCmdLine, L"--");

if (optind == argc) {
// No command-line specified. Use a default one.
appendBashArg(bashCmdLine, L"/bin/bash");
} else {
for (int i = optind; i < argc; ++i) {
appendBashArg(bashCmdLine, mbsToWcs(argv[i]));
}
for (int i = optind; i < argc; ++i) {
appendBashArg(bashCmdLine, mbsToWcs(argv[i]));
}

std::wstring cmdLine;
Expand Down

0 comments on commit 34ec0e4

Please sign in to comment.