Skip to content

Commit

Permalink
Add "start" command
Browse files Browse the repository at this point in the history
  • Loading branch information
Serious-senpai committed Jun 15, 2024
1 parent 0e8698a commit 9ab229d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 19 deletions.
25 changes: 25 additions & 0 deletions src/commands/start.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <all.hpp>

class StartCommand : public liteshell::BaseCommand
{
public:
StartCommand()
: liteshell::BaseCommand(
"start",
"Starts a new window of the command shell, run the specified command and exit.",
"",
liteshell::CommandConstraint("command", "The command line to run", true)) {}

DWORD run(const liteshell::Context &context)
{
auto command = context.get("command");
context.client->spawn_subprocess(
utils::format("%s \"%s\"", utils::get_executable_path().c_str(), command.c_str()),
true, // no effect
true);

return 0;
}
};
46 changes: 30 additions & 16 deletions src/include/client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,10 @@ namespace liteshell
{
auto final_context = context.replace_call(*executable);

auto subprocess = spawn_subprocess(final_context);
auto subprocess = spawn_subprocess(
final_context.strip_background_request().message,
final_context.is_background_request(),
false);
_environment->set_value("pid", std::to_string(subprocess->pid()));
if (final_context.is_background_request())
{
Expand Down Expand Up @@ -518,34 +521,45 @@ namespace liteshell
/**
* @brief Spawn a subprocess and execute `command` in it.
*
* @param context A context holding the command to execute.
* @param command The command to execute in the subprocess.
* @param background Whether to run the subprocess in the background.
* @param new_console Whether to run the subprocess in a new console window. If this is `true`, parameter `background`
* has no effect.
* @return A pointer to the wrapper object containing information about the subprocess.
*/
ProcessInfoWrapper *spawn_subprocess(const Context &context)
ProcessInfoWrapper *spawn_subprocess(const std::string &command, const bool background, const bool new_console)
{
auto final_context = context.strip_background_request();
DWORD flags = 0;
if (background)
{
flags |= CREATE_NEW_PROCESS_GROUP;
}
if (new_console)
{
flags |= CREATE_NEW_CONSOLE;
}

STARTUPINFOW startup_info;
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);

PROCESS_INFORMATION process_info;
auto success = CreateProcessW(
NULL, // lpApplicationName
utils::utf_convert(final_context.message).data(), // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
TRUE, // bInheritHandles
context.is_background_request() ? CREATE_NEW_PROCESS_GROUP : 0, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&startup_info, // lpStartupInfo
&process_info // lpProcessInformation
NULL, // lpApplicationName
utils::utf_convert(command).data(), // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
TRUE, // bInheritHandles
flags, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&startup_info, // lpStartupInfo
&process_info // lpProcessInformation
);

if (success)
{
ProcessInfoWrapper *wrapper = new ProcessInfoWrapper(process_info, final_context.message);
ProcessInfoWrapper *wrapper = new ProcessInfoWrapper(process_info, command);
_subprocesses.push_back(wrapper);

// Do not close the handles since we want to keep track of all subprocesses in our current shell (unless explicitly closed)
Expand All @@ -567,7 +581,7 @@ namespace liteshell
{
CloseHandle(process_info.hProcess);
CloseHandle(process_info.hThread);
throw SubprocessCreationError(utils::last_error(utils::format("Unable to create subprocess \"%s\"", final_context.message.c_str())));
throw SubprocessCreationError(utils::last_error(utils::format("Unable to create subprocess \"%s\"", command.c_str())));
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/initialize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "commands/ps.hpp"
#include "commands/resume.hpp"
#include "commands/rm.hpp"
#include "commands/start.hpp"
#include "commands/suspend.hpp"
#include "commands/volume.hpp"

Expand Down Expand Up @@ -55,6 +56,7 @@ void initialize(liteshell::Client *client)
->add_command<PsCommand>()
->add_command<ResumeCommand>()
->add_command<RmCommand>()
->add_command<StartCommand>()
->add_command<SuspendCommand>()
->add_command<VolumeCommand>();
}
13 changes: 10 additions & 3 deletions src/shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@ Type "help" to get started.
Type "help <command>" to get help about a command.
Type "<executable> <arguments> %" to run an executable in a subprocess.)";

int main(int argc, const char *argv[])
int main(int argc, const char **argv)
{
auto client_ptr = liteshell::Client::get_instance();
initialize(client_ptr.get());

std::cout << title << std::endl;
client_ptr->run_forever();
if (argc == 1)
{
std::cout << title << std::endl;
client_ptr->run_forever();
}
else
{
client_ptr->process_command(argv[1]);
}

return 0;
}

0 comments on commit 9ab229d

Please sign in to comment.