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

55 lines
1.6 KiB
C++

// SPDX-License-Identifier: Apache-2.0
#include <app/dir.h>
#include <app/private/ledger.h>
#include <app/scheduler.h>
#include <tactility/concurrent/mutex.h>
#include <tactility/filesystem/fs.h>
#include <cstring>
extern "C" {
error_t app_dir_get_cwd(char* buf, size_t size) {
auto& ledger = app_ledger();
mutex_lock(&ledger.mutex);
auto iterator = ledger.instances.find(app_scheduler_current_app_id());
if (iterator == ledger.instances.end()) {
mutex_unlock(&ledger.mutex);
return ERROR_NOT_FOUND;
}
const std::string& cwd = iterator->second.cwd;
error_t result = ERROR_NONE;
if (cwd.size() + 1 > size) {
result = ERROR_BUFFER_OVERFLOW;
} else {
memcpy(buf, cwd.c_str(), cwd.size() + 1);
}
mutex_unlock(&ledger.mutex);
return result;
}
error_t app_dir_set_cwd(const char* absolute_path) {
if (absolute_path == nullptr || absolute_path[0] != '/') {
return ERROR_INVALID_ARGUMENT;
}
// "/" is the synthetic root (a listing of mount points, see ShellFs.h) rather than a real
// directory, so directory_exists() would reject it even though it's a valid cwd.
if (strcmp(absolute_path, "/") != 0 && !directory_exists(absolute_path)) {
return ERROR_NOT_FOUND;
}
auto& ledger = app_ledger();
mutex_lock(&ledger.mutex);
auto iterator = ledger.instances.find(app_scheduler_current_app_id());
if (iterator == ledger.instances.end()) {
mutex_unlock(&ledger.mutex);
return ERROR_NOT_FOUND;
}
iterator->second.cwd = absolute_path;
mutex_unlock(&ledger.mutex);
return ERROR_NONE;
}
} // extern "C"