mirror of https://gitlab.com/nakst/essence
run busybox in posix launcher only
This commit is contained in:
parent
db3f9584b2
commit
3833e3ef82
|
@ -4,6 +4,7 @@ icon=icon_system_file_manager
|
||||||
permission_all_files=1
|
permission_all_files=1
|
||||||
permission_view_file_types=1
|
permission_view_file_types=1
|
||||||
permission_start_application=1
|
permission_start_application=1
|
||||||
|
permission_run_temporary_application=1
|
||||||
use_single_process=1
|
use_single_process=1
|
||||||
is_file_manager=1
|
is_file_manager=1
|
||||||
background_service=1
|
background_service=1
|
||||||
|
|
|
@ -825,6 +825,19 @@ int ListCallback(EsElement *element, EsMessage *message) {
|
||||||
if (entry->isFolder) {
|
if (entry->isFolder) {
|
||||||
String path = instance->folder->itemHandler->getPathForChild(instance->folder, entry);
|
String path = instance->folder->itemHandler->getPathForChild(instance->folder, entry);
|
||||||
InstanceLoadFolder(instance, path);
|
InstanceLoadFolder(instance, path);
|
||||||
|
} else if (StringEquals(entry->GetExtension(), StringFromLiteral("esx"))) {
|
||||||
|
// TODO Temporary.
|
||||||
|
String path = StringAllocateAndFormat("%s%s", STRFMT(instance->folder->path), STRFMT(entry->GetInternalName()));
|
||||||
|
|
||||||
|
if (StringEquals(path, StringFromLiteral("0:/Essence/Desktop.esx")) || StringEquals(path, StringFromLiteral("0:/Essence/Kernel.esx"))) {
|
||||||
|
EsDialogShow(instance->window, INTERFACE_STRING(FileManagerOpenFileError),
|
||||||
|
INTERFACE_STRING(FileManagerCannotOpenSystemFile),
|
||||||
|
ES_ICON_DIALOG_ERROR, ES_DIALOG_ALERT_OK_BUTTON);
|
||||||
|
} else {
|
||||||
|
EsApplicationRunTemporary(instance, STRING(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringDestroy(&path);
|
||||||
} else {
|
} else {
|
||||||
FileType *fileType = FolderEntryGetType(instance->folder, entry);
|
FileType *fileType = FolderEntryGetType(instance->folder, entry);
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,7 @@ EsHandle commandEvent;
|
||||||
char outputBuffer[262144];
|
char outputBuffer[262144];
|
||||||
uintptr_t outputBufferPosition;
|
uintptr_t outputBufferPosition;
|
||||||
EsMutex mutex;
|
EsMutex mutex;
|
||||||
volatile bool runningCommand;
|
|
||||||
int stdinWritePipe;
|
int stdinWritePipe;
|
||||||
char *command;
|
|
||||||
EsTextbox *textboxOutput, *textboxInput;
|
EsTextbox *textboxOutput, *textboxInput;
|
||||||
|
|
||||||
const EsStyle styleMonospacedTextbox = {
|
const EsStyle styleMonospacedTextbox = {
|
||||||
|
@ -33,32 +31,6 @@ const EsStyle styleMonospacedTextbox = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
char *ParseArgument(char **position) {
|
|
||||||
char *start = *position;
|
|
||||||
|
|
||||||
while (*start == ' ') {
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(*start)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *end = start;
|
|
||||||
|
|
||||||
while ((*end != ' ' || (end != start && end[-1] == '\\')) && *end) {
|
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*end) {
|
|
||||||
*end = 0;
|
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*position = end;
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteToOutputTextbox(const char *string, ptrdiff_t stringBytes) {
|
void WriteToOutputTextbox(const char *string, ptrdiff_t stringBytes) {
|
||||||
if (stringBytes == -1) {
|
if (stringBytes == -1) {
|
||||||
stringBytes = EsCRTstrlen(string);
|
stringBytes = EsCRTstrlen(string);
|
||||||
|
@ -94,14 +66,14 @@ void WriteToOutputTextbox(const char *string, ptrdiff_t stringBytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunCommandThread() {
|
void RunCommandThread() {
|
||||||
char *argv[64];
|
WriteToOutputTextbox("Starting busybox shell...\n", -1);
|
||||||
int argc = 0;
|
|
||||||
|
char *argv[3] = { (char *) "busybox", (char *) "sh", nullptr };
|
||||||
char executable[4096];
|
char executable[4096];
|
||||||
int status;
|
int status;
|
||||||
int standardOutputPipe[2];
|
int standardOutputPipe[2];
|
||||||
int standardInputPipe[2];
|
int standardInputPipe[2];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
struct timespec startTime, endTime;
|
|
||||||
|
|
||||||
char *envp[5] = {
|
char *envp[5] = {
|
||||||
(char *) "LANG=en_US.UTF-8",
|
(char *) "LANG=en_US.UTF-8",
|
||||||
|
@ -111,51 +83,7 @@ void RunCommandThread() {
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
char *commandPosition = command;
|
|
||||||
|
|
||||||
while (argc < 63) {
|
|
||||||
argv[argc] = ParseArgument(&commandPosition);
|
|
||||||
if (!argv[argc]) break;
|
|
||||||
argc++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!argc) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv[argc] = nullptr;
|
|
||||||
|
|
||||||
if (0 == EsCRTstrcmp(argv[0], "run")) {
|
|
||||||
if (argc != 2) {
|
|
||||||
WriteToOutputTextbox("\nUsage: run <absolute path to esx>\n", -1);
|
|
||||||
} else {
|
|
||||||
EsApplicationRunTemporary(instance, argv[1], EsCStringLength(argv[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteToOutputTextbox("\n----------------\n", -1);
|
|
||||||
goto done;
|
|
||||||
} else if (0 == EsCRTstrcmp(argv[0], "cd")) {
|
|
||||||
if (argc != 2) {
|
|
||||||
WriteToOutputTextbox("\nUsage: cd <path>\n", -1);
|
|
||||||
} else {
|
|
||||||
chdir(argv[1]);
|
|
||||||
|
|
||||||
WriteToOutputTextbox("\nNew working directory:\n", -1);
|
|
||||||
WriteToOutputTextbox(getcwd(nullptr, 0), -1);
|
|
||||||
WriteToOutputTextbox("\n", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteToOutputTextbox("\n----------------\n", -1);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argv[0][0] == '/') {
|
|
||||||
executable[EsStringFormat(executable, sizeof(executable) - 1, "%z", argv[0])] = 0;
|
|
||||||
} else {
|
|
||||||
executable[EsStringFormat(executable, sizeof(executable) - 1, "/Applications/POSIX/bin/%z", argv[0])] = 0;
|
executable[EsStringFormat(executable, sizeof(executable) - 1, "/Applications/POSIX/bin/%z", argv[0])] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &startTime);
|
|
||||||
|
|
||||||
pipe(standardOutputPipe);
|
pipe(standardOutputPipe);
|
||||||
pipe(standardInputPipe);
|
pipe(standardInputPipe);
|
||||||
|
@ -172,7 +100,7 @@ void RunCommandThread() {
|
||||||
WriteToOutputTextbox("\nThe executable failed to load.\n", -1);
|
WriteToOutputTextbox("\nThe executable failed to load.\n", -1);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
} else if (pid == -1) {
|
} else if (pid == -1) {
|
||||||
// TODO Report the error.
|
WriteToOutputTextbox("\nUnable to vfork().\n", -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(standardInputPipe[0]);
|
close(standardInputPipe[0]);
|
||||||
|
@ -201,22 +129,6 @@ void RunCommandThread() {
|
||||||
close(standardOutputPipe[0]);
|
close(standardOutputPipe[0]);
|
||||||
|
|
||||||
wait4(-1, &status, 0, NULL);
|
wait4(-1, &status, 0, NULL);
|
||||||
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &endTime);
|
|
||||||
|
|
||||||
{
|
|
||||||
double startTimeS = startTime.tv_sec + startTime.tv_nsec / 1000000000.0;
|
|
||||||
double endTimeS = endTime.tv_sec + endTime.tv_nsec / 1000000000.0;
|
|
||||||
char buffer[256];
|
|
||||||
size_t bytes = EsStringFormat(buffer, sizeof(buffer), "\nProcess exited with status %d.\nExecution time: %Fs.\n", status >> 8, endTimeS - startTimeS);
|
|
||||||
WriteToOutputTextbox(buffer, bytes);
|
|
||||||
WriteToOutputTextbox("\n----------------\n", -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
done:;
|
|
||||||
EsHeapFree(command);
|
|
||||||
__sync_synchronize();
|
|
||||||
runningCommand = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProcessTextboxInputMessage(EsElement *, EsMessage *message) {
|
int ProcessTextboxInputMessage(EsElement *, EsMessage *message) {
|
||||||
|
@ -225,18 +137,6 @@ int ProcessTextboxInputMessage(EsElement *, EsMessage *message) {
|
||||||
&& !message->keyboard.modifiers
|
&& !message->keyboard.modifiers
|
||||||
&& EsTextboxGetLineLength(textboxInput)) {
|
&& EsTextboxGetLineLength(textboxInput)) {
|
||||||
char *data = EsTextboxGetContents(textboxInput);
|
char *data = EsTextboxGetContents(textboxInput);
|
||||||
|
|
||||||
if (!runningCommand) {
|
|
||||||
runningCommand = true;
|
|
||||||
command = data;
|
|
||||||
|
|
||||||
EsTextboxInsert(textboxOutput, "\n> ", -1, false);
|
|
||||||
EsTextboxInsert(textboxOutput, command, -1, false);
|
|
||||||
EsTextboxInsert(textboxOutput, "\n", -1, false);
|
|
||||||
EsTextboxEnsureCaretVisible(textboxOutput, false);
|
|
||||||
|
|
||||||
EsEventSet(commandEvent);
|
|
||||||
} else {
|
|
||||||
EsTextboxInsert(textboxOutput, data, -1, false);
|
EsTextboxInsert(textboxOutput, data, -1, false);
|
||||||
EsTextboxInsert(textboxOutput, "\n", -1, false);
|
EsTextboxInsert(textboxOutput, "\n", -1, false);
|
||||||
EsMutexAcquire(&mutex);
|
EsMutexAcquire(&mutex);
|
||||||
|
@ -248,8 +148,6 @@ int ProcessTextboxInputMessage(EsElement *, EsMessage *message) {
|
||||||
|
|
||||||
EsMutexRelease(&mutex);
|
EsMutexRelease(&mutex);
|
||||||
EsHeapFree(data);
|
EsHeapFree(data);
|
||||||
}
|
|
||||||
|
|
||||||
EsTextboxClear(textboxInput, false);
|
EsTextboxClear(textboxInput, false);
|
||||||
return ES_HANDLED;
|
return ES_HANDLED;
|
||||||
}
|
}
|
||||||
|
@ -259,6 +157,8 @@ int ProcessTextboxInputMessage(EsElement *, EsMessage *message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageLoopThread(EsGeneric) {
|
void MessageLoopThread(EsGeneric) {
|
||||||
|
// Cannot access the C standard library on this thread!
|
||||||
|
|
||||||
EsMessageMutexAcquire();
|
EsMessageMutexAcquire();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -276,11 +176,11 @@ void MessageLoopThread(EsGeneric) {
|
||||||
EsTextboxEnableSmartQuotes(textboxInput, false);
|
EsTextboxEnableSmartQuotes(textboxInput, false);
|
||||||
textboxInput->messageUser = ProcessTextboxInputMessage;
|
textboxInput->messageUser = ProcessTextboxInputMessage;
|
||||||
EsElementFocus(textboxInput);
|
EsElementFocus(textboxInput);
|
||||||
|
EsEventSet(commandEvent); // Ready to receive output.
|
||||||
} else if (message->type == MSG_RECEIVED_OUTPUT) {
|
} else if (message->type == MSG_RECEIVED_OUTPUT) {
|
||||||
EsMutexAcquire(&mutex);
|
EsMutexAcquire(&mutex);
|
||||||
|
|
||||||
if (outputBufferPosition) {
|
if (outputBufferPosition) {
|
||||||
// EsPrint("Inserting %d bytes...\n", outputBufferPosition);
|
|
||||||
EsTextboxMoveCaretRelative(textboxOutput, ES_TEXTBOX_MOVE_CARET_ALL);
|
EsTextboxMoveCaretRelative(textboxOutput, ES_TEXTBOX_MOVE_CARET_ALL);
|
||||||
EsTextboxInsert(textboxOutput, outputBuffer, outputBufferPosition, false);
|
EsTextboxInsert(textboxOutput, outputBuffer, outputBufferPosition, false);
|
||||||
EsTextboxEnsureCaretVisible(textboxOutput, false);
|
EsTextboxEnsureCaretVisible(textboxOutput, false);
|
||||||
|
@ -299,18 +199,8 @@ int main(int argc, char **argv) {
|
||||||
commandEvent = EsEventCreate(true);
|
commandEvent = EsEventCreate(true);
|
||||||
EsMessageMutexRelease();
|
EsMessageMutexRelease();
|
||||||
EsThreadCreate(MessageLoopThread, nullptr, 0);
|
EsThreadCreate(MessageLoopThread, nullptr, 0);
|
||||||
|
|
||||||
#if 0
|
|
||||||
runningCommand = true;
|
|
||||||
command = (char *) EsHeapAllocate(128, true);
|
|
||||||
EsStringFormat(command, 128, "gcc es/util/build_core.c -g");
|
|
||||||
EsEventSet(commandEvent);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
EsWaitSingle(commandEvent);
|
EsWaitSingle(commandEvent);
|
||||||
RunCommandThread();
|
RunCommandThread();
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -304,6 +304,7 @@ DEFINE_INTERFACE_STRING(FileManagerColumnSize, "Size");
|
||||||
DEFINE_INTERFACE_STRING(FileManagerOpenFolderTask, "Opening folder" ELLIPSIS);
|
DEFINE_INTERFACE_STRING(FileManagerOpenFolderTask, "Opening folder" ELLIPSIS);
|
||||||
DEFINE_INTERFACE_STRING(FileManagerOpenFileError, "The file could not be opened.");
|
DEFINE_INTERFACE_STRING(FileManagerOpenFileError, "The file could not be opened.");
|
||||||
DEFINE_INTERFACE_STRING(FileManagerNoRegisteredApplicationsForFile, "None of the applications installed on this computer can open this type of file.");
|
DEFINE_INTERFACE_STRING(FileManagerNoRegisteredApplicationsForFile, "None of the applications installed on this computer can open this type of file.");
|
||||||
|
DEFINE_INTERFACE_STRING(FileManagerCannotOpenSystemFile, "This is a system file which has already been loaded.");
|
||||||
DEFINE_INTERFACE_STRING(FileManagerFolderNamePrompt, "Folder name:");
|
DEFINE_INTERFACE_STRING(FileManagerFolderNamePrompt, "Folder name:");
|
||||||
DEFINE_INTERFACE_STRING(FileManagerNewFolderAction, "Create");
|
DEFINE_INTERFACE_STRING(FileManagerNewFolderAction, "Create");
|
||||||
DEFINE_INTERFACE_STRING(FileManagerNewFolderTask, "Creating folder" ELLIPSIS);
|
DEFINE_INTERFACE_STRING(FileManagerNewFolderTask, "Creating folder" ELLIPSIS);
|
||||||
|
|
Loading…
Reference in New Issue