-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathlinuxify.hpp
More file actions
148 lines (116 loc) · 3.81 KB
/
linuxify.hpp
File metadata and controls
148 lines (116 loc) · 3.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Linuxify Shell Client Library
// Include this header to execute commands through the Linuxify shell
// This header is installed to system include directories during Linuxify installation
#pragma once
#include <windows.h>
#include <string>
#include <vector>
#include <sstream>
namespace Linuxify {
const char* PIPE_NAME = "\\\\.\\pipe\\LinuxifyShell";
const DWORD BUFFER_SIZE = 65536;
struct Result {
int exitCode;
std::string output;
bool success() const { return exitCode == 0; }
operator std::string() const { return output; }
operator bool() const { return exitCode == 0; }
};
class Shell {
private:
HANDLE hPipe;
bool connected;
bool ensureConnection() {
if (connected && hPipe != INVALID_HANDLE_VALUE) return true;
hPipe = CreateFileA(
PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL
);
connected = (hPipe != INVALID_HANDLE_VALUE);
return connected;
}
std::string sendRequest(const std::string& request) {
HANDLE hPipe = CreateFileA(
PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL
);
if (hPipe == INVALID_HANDLE_VALUE) return "";
DWORD bytesWritten;
if (!WriteFile(hPipe, request.c_str(), (DWORD)request.length(), &bytesWritten, NULL)) {
CloseHandle(hPipe);
return "";
}
char buffer[BUFFER_SIZE];
DWORD bytesRead;
std::string response;
if (ReadFile(hPipe, buffer, BUFFER_SIZE - 1, &bytesRead, NULL) && bytesRead > 0) {
buffer[bytesRead] = '\0';
response = buffer;
}
CloseHandle(hPipe);
return response;
}
public:
Shell() : hPipe(INVALID_HANDLE_VALUE), connected(false) {}
~Shell() { disconnect(); }
void disconnect() {
if (hPipe != INVALID_HANDLE_VALUE) {
CloseHandle(hPipe);
hPipe = INVALID_HANDLE_VALUE;
connected = false;
}
}
bool isConnected() const { return connected; }
Result exec(const std::string& command) {
Result result = {-1, ""};
std::string response = sendRequest("EXEC " + command);
if (response.empty()) {
result.output = "Error: Cannot connect to Linuxify shell";
return result;
}
size_t newline = response.find('\n');
if (newline != std::string::npos) {
result.exitCode = std::stoi(response.substr(0, newline));
result.output = response.substr(newline + 1);
} else {
result.exitCode = 0;
result.output = response;
}
return result;
}
std::string operator()(const std::string& command) {
return exec(command).output;
}
bool ping() {
return sendRequest("PING") == "PONG";
}
std::string status() {
return sendRequest("STATUS");
}
};
static Shell defaultShell;
inline Result exec(const std::string& command) {
return defaultShell.exec(command);
}
inline std::string operator""_sh(const char* cmd, size_t) {
return defaultShell.exec(cmd).output;
}
inline bool isRunning() {
return defaultShell.ping();
}
inline std::string pwd() { return defaultShell.exec("pwd").output; }
inline std::string ls(const std::string& path = "") {
return defaultShell.exec("ls " + path).output;
}
inline std::string cat(const std::string& file) {
return defaultShell.exec("cat " + file).output;
}
inline std::string echo(const std::string& msg) {
return defaultShell.exec("echo " + msg).output;
}
}
inline Linuxify::Result linuxify(const std::string& command) {
return Linuxify::exec(command);
}