Ken Van Hoeylandt 79d3dd4fdb
Improvements for apps, filesystems, terminal and shell (#659)
app-module

- Apps now have support for:
  - environment variables (inherit from parent app)
  - current workdir
  - window size (when running in terminal)
- Add type aliases like `AppId` and `PackageId`
- Remove data duplication between ledger and app instance records: create `AppManifestSet`
- `AppManifest` usage safety improved: pass by value where needed, or use `AppId` instead of a manifest.

Terminal and shell

- Moved shell commands into coreutils-module as proper apps.
- Refine stack size for terminal and shell because apps now run with their own task and stack (including in-memory apps)

Platform

- Fix for listing root dir on ESP32: wrap posix directory functions and wire in file systems.
- Moved all platform-specific file system init code to platform subprojects

Other

- Fix for screenshot capture (issue with paths)
- Fixes for coreutils app correctness
- Memory optimizations (use more PSRAM where possible) in various locations such as app-module, shell and terminal.
- `ls` and `help` commands now use terminal width and show columns of data by default
- Created fs helpers at `TactilityKernel/include/tactility/filesystem/fs.h` (partially ported from `ShellFs`)
2026-09-25 08:29:27 +02:00

84 lines
2.6 KiB
C++

// SPDX-License-Identifier: Apache-2.0
#ifndef ESP_PLATFORM
#include <tactility/error.h>
#include <tactility/filesystem/file_system.h>
#include <tactility/log.h>
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <cstring>
namespace {
constexpr auto* TAG = "platform-posix";
// A plain host directory has no real mount/unmount step to perform.
// mounted" here just tracks whether file_system_remove()'s precondition has been satisfied.
struct DirectoryFsData {
char path[PATH_MAX];
bool mounted;
};
DirectoryFsData system_fs_data;
DirectoryFsData data_fs_data;
DirectoryFsData root_fs_data;
error_t mount(void* data) {
static_cast<DirectoryFsData*>(data)->mounted = true;
return ERROR_NONE;
}
error_t unmount(void* data) {
static_cast<DirectoryFsData*>(data)->mounted = false;
return ERROR_NONE;
}
bool is_mounted(void* data) {
return static_cast<DirectoryFsData*>(data)->mounted;
}
error_t get_path(void* data, char* out_path, size_t out_path_size) {
auto* fs_data = static_cast<DirectoryFsData*>(data);
if (strlen(fs_data->path) >= out_path_size) {
return ERROR_BUFFER_OVERFLOW;
}
strcpy(out_path, fs_data->path);
return ERROR_NONE;
}
const FileSystemApi directory_fs_api = {
.mount = mount,
.unmount = unmount,
.is_mounted = is_mounted,
.get_path = get_path,
};
// relative_path is resolved against the process' current working directory.
// The simulator is expected to run with Data/ as its working directory, so "data"/"system" here match the real on-disk folder names.
// realpath() converts it to a real absolute path once, up front.
// Callers elsewhere (e.g. the shell) that ask for this filesystem's path via file_system_get_path() then
// get something meaningful regardless of their own notion of "current directory", real or virtual.
FileSystem* registerDirectoryFs(const char* name, const char* relativePath, DirectoryFsData* outData) {
if (realpath(relativePath, outData->path) == nullptr) {
LOG_E(TAG, "Failed to resolve '%s' to an absolute path: %s", relativePath, strerror(errno));
return nullptr;
}
outData->mounted = true;
return file_system_add(name, &directory_fs_api, outData);
}
} // namespace
error_t platform_posix_start_partitions() {
registerDirectoryFs("system", "system", &system_fs_data);
registerDirectoryFs("data", "data", &data_fs_data);
// "data"/"system" live somewhere under here (wherever the process was launched from). U
// Unlike ESP32, POSIX genuinely has a real "/", so it gets registered too.
registerDirectoryFs("root", "/", &root_fs_data);
return ERROR_NONE;
}
#endif // ESP_PLATFORM