Module linux_plus_plus.stdlib
linux++ — Standard Library (Layer 2)
This module provides a compact, dependency-free standard library for the linux++ project. It intentionally exposes a small, stable façade used by the upper layers (shell, kernel and applications) and concentrates common utility code that would otherwise be duplicated across the codebase.
Key components:
- IOManager: unified helpers for terminal and file I/O, low-level pipe
helpers and convenience redirect context managers.
- SignalHandler: small multi-callback signal dispatcher and helpers for
registering Ctrl+C and termination handlers.
- EnvManager: environment and configuration handling (PATH resolution,
config file loading and a merged view of local and host environment).
- AliasStore: shell alias table with safe expansion semantics.
Design goals: - Use only Python standard library modules so this layer is easy to test and bundle. - Keep interfaces minimal and explicit — callers should not rely on hidden side-effects.
Functions
def main()-
Expand source code
def main(): Stdlib.boot() io = Stdlib.io env = Stdlib.env io.write("=== linux++ stdlib self-test ===\n") # IOManager tmp = os.path.join(os.path.expanduser("~"), "_lpp_test.txt") IOManager.write_file(tmp, "hello from linux++\n") IOManager.append_file(tmp, "second line\n") content = IOManager.read_file(tmp) assert "hello" in content and "second" in content os.unlink(tmp) io.write("[IOManager] read/write/append: OK") # pipe r, w = IOManager.make_pipe() IOManager.pipe_write(w, "ping") result = IOManager.pipe_read(r) assert result == "ping" io.write("[IOManager] pipe read/write: OK") # EnvManager EnvManager.set("LPP_TEST", "42") assert EnvManager.get("LPP_TEST") == "42" EnvManager.unset("LPP_TEST") assert EnvManager.get("LPP_TEST") == "" io.write("[EnvManager] set/get/unset: OK") # PATH resolution python_cmd = "python3" if not IS_WINDOWS else "python" found = EnvManager.resolve_command(python_cmd) io.write(f"[EnvManager] resolve python: {found or 'not found'}") # AliasStore AliasStore.set("ll", "ls -la") expanded = AliasStore.expand(["ll", "/tmp"]) assert expanded == ["ls", "-la", "/tmp"] io.write("[AliasStore] alias expand: OK") # SignalHandler io.write("[SignalHandler] registered SIGINT: OK") io.write("\nAll stdlib tests passed.")
Classes
class AliasStore-
Expand source code
class AliasStore: """A lightweight alias table used by the shell. Aliases map a single token to an expanded command string. Expansion is performed by `expand()` which supports recursive alias substitution with a safety limit to avoid infinite loops. """ _store: dict[str, str] = {} @classmethod def set(cls, alias: str, expansion: str) -> None: cls._store[alias] = expansion @classmethod def get(cls, alias: str) -> Optional[str]: return cls._store.get(alias) @classmethod def unset(cls, alias: str) -> None: cls._store.pop(alias, None) @classmethod def all(cls) -> dict[str, str]: return dict(cls._store) @classmethod def expand(cls, tokens: list[str]) -> list[str]: """Expand the head token using the alias table. If the first token matches an alias the expansion string is split on whitespace and substituted for the head token. The process repeats up to 10 times to support chained aliases while avoiding accidental infinite recursion. """ seen = set() for _ in range(10): if not tokens: break head = tokens[0] if head in seen: break expansion = cls._store.get(head) if expansion is None: break seen.add(head) tokens = expansion.split() + tokens[1:] return tokensA lightweight alias table used by the shell.
Aliases map a single token to an expanded command string. Expansion is performed by
expand()which supports recursive alias substitution with a safety limit to avoid infinite loops.Static methods
def all() ‑> dict[str, str]def expand(tokens: list[str]) ‑> list[str]-
Expand the head token using the alias table.
If the first token matches an alias the expansion string is split on whitespace and substituted for the head token. The process repeats up to 10 times to support chained aliases while avoiding accidental infinite recursion.
def get(alias: str) ‑> str | Nonedef set(alias: str, expansion: str) ‑> Nonedef unset(alias: str) ‑> None
class EnvManager-
Expand source code
class EnvManager: """Environment and configuration helper for linux++. `EnvManager` maintains a merged view of the host environment and a local store used by the shell and applications. Local variables may shadow host environment keys and can optionally be exported to `os.environ` so child processes inherit them. Responsibilities include PATH resolution, loading/saving a simple INI config (`.linuxpprc`) and providing helpers such as `username()` and `hostname()` used in prompt rendering. """ _local: dict[str, str] = {} # --- get / set / unset --- @classmethod def get(cls, key: str, default: str = "") -> str: """Return the value for `key`, preferring the local store. If the key is not present in the local store the method falls back to `os.environ` and finally returns `default`. """ return cls._local.get(key) or os.environ.get(key, default) @classmethod def set(cls, key: str, value: str, export: bool = False) -> None: """ Set a variable. export=True also writes to os.environ (child processes inherit it). """ cls._local[key] = value if export: os.environ[key] = value @classmethod def unset(cls, key: str) -> None: """Remove `key` from both the local store and host environment. This operation is idempotent and will silently ignore missing keys. """ cls._local.pop(key, None) os.environ.pop(key, None) @classmethod def all(cls) -> dict[str, str]: """Merged view: os.environ + local overrides.""" merged = dict(os.environ) merged.update(cls._local) return merged # --- PATH resolution --- @classmethod def path_dirs(cls) -> list[str]: """Return the `PATH` environment variable split into directories. Uses `;` on Windows and `:` on POSIX-like platforms. """ raw = cls.get("PATH", "") sep = ";" if IS_WINDOWS else ":" return [d for d in raw.split(sep) if d] @classmethod def resolve_command(cls, name: str) -> Optional[str]: """ Find the full path of a command by searching PATH. Returns None if not found. Uses only os.stat — no shutil.which. """ # If it already looks like a path, just check directly if os.sep in name or (IS_WINDOWS and "/" in name): return name if IOManager.file_exists(name) else None extensions = ["", ".exe", ".cmd", ".bat"] if IS_WINDOWS else [""] for directory in cls.path_dirs(): for ext in extensions: candidate = os.path.join(directory, name + ext) try: st = os.stat(candidate) # On Unix, check execute bit if not IS_WINDOWS: if st.st_mode & 0o111: return candidate else: return candidate except (FileNotFoundError, NotADirectoryError): continue return None # --- config file (.linuxpprc) --- @classmethod def load_config(cls, path: Optional[str] = None) -> None: """ Load a .linuxpprc config file (INI format). Defaults to ~/.linuxpprc Example .linuxpprc: [env] EDITOR = nano PAGER = less [aliases] ll = ls -la ..= cd .. """ if path is None: path = os.path.join(os.path.expanduser("~"), ".linuxpprc") if not IOManager.file_exists(path): return cfg = configparser.ConfigParser() cfg.read(path, encoding="utf-8") # Load [env] section into EnvManager if cfg.has_section("env"): for key, value in cfg.items("env"): cls.set(key.upper(), value, export=True) # Load [aliases] into AliasStore if cfg.has_section("aliases"): for alias, expansion in cfg.items("aliases"): AliasStore.set(alias, expansion) @classmethod def save_config(cls, path: Optional[str] = None) -> None: """Write current local env and aliases to a .linuxpprc file. The method writes the local variables (lowercased) under the `[env]` section and current aliases under `[aliases]`. """ if path is None: path = os.path.join(os.path.expanduser("~"), ".linuxpprc") cfg = configparser.ConfigParser() cfg["env"] = { k.lower(): v for k, v in cls._local.items() } cfg["aliases"] = dict(AliasStore._store) with open(path, "w", encoding="utf-8") as f: cfg.write(f) # --- common helpers --- @classmethod def home(cls) -> str: """Return the configured home directory for the current user.""" return os.path.expanduser("~") @classmethod def username(cls) -> str: """Return a best-effort username used for prompts. The method checks common environment keys and falls back to `user`. """ return cls.get("USER") or cls.get("USERNAME") or "user" @classmethod def hostname(cls) -> str: """Return the system hostname used in prompt rendering.""" import socket return socket.gethostname()Environment and configuration helper for linux++.
EnvManagermaintains a merged view of the host environment and a local store used by the shell and applications. Local variables may shadow host environment keys and can optionally be exported toos.environso child processes inherit them.Responsibilities include PATH resolution, loading/saving a simple INI config (
.linuxpprc) and providing helpers such asusername()andhostname()used in prompt rendering.Static methods
def all() ‑> dict[str, str]-
Merged view: os.environ + local overrides.
def get(key: str, default: str = '') ‑> str-
Return the value for
key, preferring the local store.If the key is not present in the local store the method falls back to
os.environand finally returnsdefault. def home() ‑> str-
Return the configured home directory for the current user.
def hostname() ‑> str-
Return the system hostname used in prompt rendering.
def load_config(path: str | None = None) ‑> None-
Load a .linuxpprc config file (INI format). Defaults to ~/.linuxpprc
Example .linuxpprc: [env] EDITOR = nano PAGER = less
[aliases] ll = ls -la ..= cd .. def path_dirs() ‑> list[str]-
Return the
PATHenvironment variable split into directories.Uses
;on Windows and:on POSIX-like platforms. def resolve_command(name: str) ‑> str | None-
Find the full path of a command by searching PATH. Returns None if not found. Uses only os.stat — no shutil.which.
def save_config(path: str | None = None) ‑> None-
Write current local env and aliases to a .linuxpprc file.
The method writes the local variables (lowercased) under the
[env]section and current aliases under[aliases]. def set(key: str, value: str, export: bool = False) ‑> None-
Set a variable. export=True also writes to os.environ (child processes inherit it).
def unset(key: str) ‑> None-
Remove
keyfrom both the local store and host environment.This operation is idempotent and will silently ignore missing keys.
def username() ‑> str-
Return a best-effort username used for prompts.
The method checks common environment keys and falls back to
user.
class IOManager-
Expand source code
class IOManager: """High-level I/O primitives used across linux++. `IOManager` centralises common I/O operations so higher-level code can work with text and files in a consistent way without repeatedly dealing with low-level `os` file descriptors. The class provides: - stdout/stderr helpers (`write`, `error`), - blocking line and full-stdin readers for pipelines, - low-level file operations using `os.open`/`os.read` to avoid implicit buffering differences across platforms, - pipe helpers returning raw file descriptors for use with `os.pipe()`, - context managers for temporarily redirecting `sys.stdin`/`sys.stdout`. All methods use only standard library facilities so this module remains portable and easy to unit-test. """ # --- stdout / stderr --- @staticmethod def write(text: str, end: str = "\n") -> None: sys.stdout.write(text + end) sys.stdout.flush() @staticmethod def error(text: str, end: str = "\n") -> None: sys.stderr.write(text + end) sys.stderr.flush() @staticmethod def read_line(prompt: str = "") -> str: """Read a single line from standard input using `input()`. Returns an empty string on EOF to make callers' control flow simpler (no exception handling required). """ try: return input(prompt) except EOFError: return "" @staticmethod def read_all_stdin() -> str: """Read and return the entire contents of standard input. Useful when the shell or a builtin should consume piped input completely before processing. """ return sys.stdin.read() # --- file I/O (low-level os module, no pathlib/shutil) --- @staticmethod def open_file(path: str, mode: str = "r", encoding: str = "utf-8") -> io.TextIOWrapper: """ Open a file and return a file object. Caller is responsible for closing (use with `with`). """ binary_modes = {"rb", "wb", "ab", "r+b", "w+b"} if mode in binary_modes: return open(path, mode) return open(path, mode, encoding=encoding) @staticmethod def read_file(path: str, encoding: str = "utf-8") -> str: """Read the entire file `path` and return its contents decoded. The implementation uses low-level `os.read` to avoid differences in platform newline handling and to give predictable memory behaviour for moderately-sized files. Caller receives a decoded `str`. """ fd = os.open(path, os.O_RDONLY) try: chunks = [] while True: chunk = os.read(fd, 4096) if not chunk: break chunks.append(chunk) return b"".join(chunks).decode(encoding) finally: os.close(fd) @staticmethod def write_file(path: str, content: str, encoding: str = "utf-8") -> None: """Write `content` to `path`, creating or truncating the file. New files are created with mode `0o644`. Exceptions from the host filesystem (e.g. PermissionError, OSError) propagate to the caller. """ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC fd = os.open(path, flags, 0o644) try: os.write(fd, content.encode(encoding)) finally: os.close(fd) @staticmethod def append_file(path: str, content: str, encoding: str = "utf-8") -> None: """Append `content` to `path`, creating it if necessary. Uses `os.O_APPEND` to ensure writes are appended atomically on POSIX systems. """ flags = os.O_WRONLY | os.O_CREAT | os.O_APPEND fd = os.open(path, flags, 0o644) try: os.write(fd, content.encode(encoding)) finally: os.close(fd) @staticmethod def read_lines(path: str, encoding: str = "utf-8") -> list[str]: """Read file as a list of lines (no trailing newlines).""" return IOManager.read_file(path, encoding).splitlines() @staticmethod def file_exists(path: str) -> bool: try: os.stat(path) return True except FileNotFoundError: return False @staticmethod def file_size(path: str) -> int: return os.stat(path).st_size # --- pipe I/O --- @staticmethod def make_pipe() -> tuple[int, int]: """ Create an OS-level pipe. Returns (read_fd, write_fd). """ return os.pipe() @staticmethod def pipe_write(write_fd: int, data: str, encoding: str = "utf-8") -> None: """Write `data` to a pipe file descriptor and close it. This helper encodes the string and ensures the write end of the pipe is closed after writing to signal EOF to the reader. """ os.write(write_fd, data.encode(encoding)) os.close(write_fd) @staticmethod def pipe_read(read_fd: int, encoding: str = "utf-8") -> str: """Read all data from a pipe file descriptor and return decoded text. The function closes the read end when finished. """ chunks = [] while True: chunk = os.read(read_fd, 4096) if not chunk: break chunks.append(chunk) os.close(read_fd) return b"".join(chunks).decode(encoding) # --- redirect helpers (used by shell for > >> <) --- @staticmethod def redirect_stdout_to_file(path: str): """ Context manager: redirects stdout to a file for the duration of the block. Usage: with IOManager.redirect_stdout_to_file("/tmp/out.txt"): IOManager.write("this goes to the file") """ return _RedirectContext(path, "w", sys.stdout, "stdout") @staticmethod def append_stdout_to_file(path: str): """Context manager: appends stdout to file (>>).""" return _RedirectContext(path, "a", sys.stdout, "stdout") @staticmethod def redirect_stdin_from_file(path: str): """Context manager: reads stdin from file (<).""" return _RedirectContext(path, "r", sys.stdin, "stdin")High-level I/O primitives used across linux++.
IOManagercentralises common I/O operations so higher-level code can work with text and files in a consistent way without repeatedly dealing with low-levelosfile descriptors. The class provides: - stdout/stderr helpers (write,error), - blocking line and full-stdin readers for pipelines, - low-level file operations usingos.open/os.readto avoid implicit buffering differences across platforms, - pipe helpers returning raw file descriptors for use withos.pipe(), - context managers for temporarily redirectingsys.stdin/sys.stdout.All methods use only standard library facilities so this module remains portable and easy to unit-test.
Static methods
def append_file(path: str, content: str, encoding: str = 'utf-8') ‑> None-
Expand source code
@staticmethod def append_file(path: str, content: str, encoding: str = "utf-8") -> None: """Append `content` to `path`, creating it if necessary. Uses `os.O_APPEND` to ensure writes are appended atomically on POSIX systems. """ flags = os.O_WRONLY | os.O_CREAT | os.O_APPEND fd = os.open(path, flags, 0o644) try: os.write(fd, content.encode(encoding)) finally: os.close(fd)Append
contenttopath, creating it if necessary.Uses
os.O_APPENDto ensure writes are appended atomically on POSIX systems. def append_stdout_to_file(path: str)-
Expand source code
@staticmethod def append_stdout_to_file(path: str): """Context manager: appends stdout to file (>>).""" return _RedirectContext(path, "a", sys.stdout, "stdout")Context manager: appends stdout to file (>>).
def error(text: str, end: str = '\n') ‑> None-
Expand source code
@staticmethod def error(text: str, end: str = "\n") -> None: sys.stderr.write(text + end) sys.stderr.flush() def file_exists(path: str) ‑> bool-
Expand source code
@staticmethod def file_exists(path: str) -> bool: try: os.stat(path) return True except FileNotFoundError: return False def file_size(path: str) ‑> int-
Expand source code
@staticmethod def file_size(path: str) -> int: return os.stat(path).st_size def make_pipe() ‑> tuple[int, int]-
Expand source code
@staticmethod def make_pipe() -> tuple[int, int]: """ Create an OS-level pipe. Returns (read_fd, write_fd). """ return os.pipe()Create an OS-level pipe. Returns (read_fd, write_fd).
def open_file(path: str, mode: str = 'r', encoding: str = 'utf-8') ‑> _io.TextIOWrapper-
Expand source code
@staticmethod def open_file(path: str, mode: str = "r", encoding: str = "utf-8") -> io.TextIOWrapper: """ Open a file and return a file object. Caller is responsible for closing (use with `with`). """ binary_modes = {"rb", "wb", "ab", "r+b", "w+b"} if mode in binary_modes: return open(path, mode) return open(path, mode, encoding=encoding)Open a file and return a file object. Caller is responsible for closing (use with
with). def pipe_read(read_fd: int, encoding: str = 'utf-8') ‑> str-
Expand source code
@staticmethod def pipe_read(read_fd: int, encoding: str = "utf-8") -> str: """Read all data from a pipe file descriptor and return decoded text. The function closes the read end when finished. """ chunks = [] while True: chunk = os.read(read_fd, 4096) if not chunk: break chunks.append(chunk) os.close(read_fd) return b"".join(chunks).decode(encoding)Read all data from a pipe file descriptor and return decoded text.
The function closes the read end when finished.
def pipe_write(write_fd: int, data: str, encoding: str = 'utf-8') ‑> None-
Expand source code
@staticmethod def pipe_write(write_fd: int, data: str, encoding: str = "utf-8") -> None: """Write `data` to a pipe file descriptor and close it. This helper encodes the string and ensures the write end of the pipe is closed after writing to signal EOF to the reader. """ os.write(write_fd, data.encode(encoding)) os.close(write_fd)Write
datato a pipe file descriptor and close it.This helper encodes the string and ensures the write end of the pipe is closed after writing to signal EOF to the reader.
def read_all_stdin() ‑> str-
Expand source code
@staticmethod def read_all_stdin() -> str: """Read and return the entire contents of standard input. Useful when the shell or a builtin should consume piped input completely before processing. """ return sys.stdin.read()Read and return the entire contents of standard input.
Useful when the shell or a builtin should consume piped input completely before processing.
def read_file(path: str, encoding: str = 'utf-8') ‑> str-
Expand source code
@staticmethod def read_file(path: str, encoding: str = "utf-8") -> str: """Read the entire file `path` and return its contents decoded. The implementation uses low-level `os.read` to avoid differences in platform newline handling and to give predictable memory behaviour for moderately-sized files. Caller receives a decoded `str`. """ fd = os.open(path, os.O_RDONLY) try: chunks = [] while True: chunk = os.read(fd, 4096) if not chunk: break chunks.append(chunk) return b"".join(chunks).decode(encoding) finally: os.close(fd)Read the entire file
pathand return its contents decoded.The implementation uses low-level
os.readto avoid differences in platform newline handling and to give predictable memory behaviour for moderately-sized files. Caller receives a decodedstr. def read_line(prompt: str = '') ‑> str-
Expand source code
@staticmethod def read_line(prompt: str = "") -> str: """Read a single line from standard input using `input()`. Returns an empty string on EOF to make callers' control flow simpler (no exception handling required). """ try: return input(prompt) except EOFError: return ""Read a single line from standard input using
input().Returns an empty string on EOF to make callers' control flow simpler (no exception handling required).
def read_lines(path: str, encoding: str = 'utf-8') ‑> list[str]-
Expand source code
@staticmethod def read_lines(path: str, encoding: str = "utf-8") -> list[str]: """Read file as a list of lines (no trailing newlines).""" return IOManager.read_file(path, encoding).splitlines()Read file as a list of lines (no trailing newlines).
def redirect_stdin_from_file(path: str)-
Expand source code
@staticmethod def redirect_stdin_from_file(path: str): """Context manager: reads stdin from file (<).""" return _RedirectContext(path, "r", sys.stdin, "stdin")Context manager: reads stdin from file (<).
def redirect_stdout_to_file(path: str)-
Expand source code
@staticmethod def redirect_stdout_to_file(path: str): """ Context manager: redirects stdout to a file for the duration of the block. Usage: with IOManager.redirect_stdout_to_file("/tmp/out.txt"): IOManager.write("this goes to the file") """ return _RedirectContext(path, "w", sys.stdout, "stdout")Context manager: redirects stdout to a file for the duration of the block.
Usage
with IOManager.redirect_stdout_to_file("/tmp/out.txt"): IOManager.write("this goes to the file")
def write(text: str, end: str = '\n') ‑> None-
Expand source code
@staticmethod def write(text: str, end: str = "\n") -> None: sys.stdout.write(text + end) sys.stdout.flush() def write_file(path: str, content: str, encoding: str = 'utf-8') ‑> None-
Expand source code
@staticmethod def write_file(path: str, content: str, encoding: str = "utf-8") -> None: """Write `content` to `path`, creating or truncating the file. New files are created with mode `0o644`. Exceptions from the host filesystem (e.g. PermissionError, OSError) propagate to the caller. """ flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC fd = os.open(path, flags, 0o644) try: os.write(fd, content.encode(encoding)) finally: os.close(fd)Write
contenttopath, creating or truncating the file.New files are created with mode
0o644. Exceptions from the host filesystem (e.g. PermissionError, OSError) propagate to the caller.
class SignalHandler-
Expand source code
class SignalHandler: """A small, multi-callback signal dispatcher. Python's `signal.signal()` allows a single handler per signal; this helper enables multiple callbacks to be registered for the same signal and calls them in registration order. It also provides convenience methods for registering common handlers (e.g. `on_ctrl_c`). On Windows platform support is limited to the signals available there (commonly SIGINT and SIGTERM). """ _handlers: dict[int, list[Callable]] = {} @classmethod def register(cls, sig: int, handler: Callable) -> None: """ Register a callback for a signal. Multiple callbacks per signal are supported (called in order). """ if sig not in cls._handlers: cls._handlers[sig] = [] signal.signal(sig, cls._dispatch) cls._handlers[sig].append(handler) @classmethod def _dispatch(cls, sig: int, frame) -> None: for handler in cls._handlers.get(sig, []): try: handler(sig, frame) except Exception: pass @classmethod def on_ctrl_c(cls, handler: Callable) -> None: """Register a Ctrl+C (SIGINT) handler. The handler will be called with the `(sig, frame)` signature just like a normal signal handler. """ cls.register(signal.SIGINT, handler) @classmethod def on_terminate(cls, handler: Callable) -> None: """Register a SIGTERM handler when supported by the platform. On Windows this is a no-op because SIGTERM is not always available. """ if not IS_WINDOWS: cls.register(signal.SIGTERM, handler) @classmethod def ignore(cls, sig: int) -> None: signal.signal(sig, signal.SIG_IGN) @classmethod def reset(cls, sig: int) -> None: signal.signal(sig, signal.SIG_DFL) cls._handlers.pop(sig, None) @classmethod def reset_all(cls) -> None: for sig in list(cls._handlers): cls.reset(sig) # --- convenience: block SIGINT during critical sections --- @staticmethod def block_interrupt(): """ Context manager that suppresses Ctrl+C for a block. Usage: with SignalHandler.block_interrupt(): save_state() # won't be interrupted """ return _BlockInterrupt()A small, multi-callback signal dispatcher.
Python's
signal.signal()allows a single handler per signal; this helper enables multiple callbacks to be registered for the same signal and calls them in registration order. It also provides convenience methods for registering common handlers (e.g.on_ctrl_c). On Windows platform support is limited to the signals available there (commonly SIGINT and SIGTERM).Static methods
def block_interrupt()-
Expand source code
@staticmethod def block_interrupt(): """ Context manager that suppresses Ctrl+C for a block. Usage: with SignalHandler.block_interrupt(): save_state() # won't be interrupted """ return _BlockInterrupt()Context manager that suppresses Ctrl+C for a block.
Usage
with SignalHandler.block_interrupt(): save_state() # won't be interrupted
def ignore(sig: int) ‑> Nonedef on_ctrl_c(handler: Callable) ‑> None-
Register a Ctrl+C (SIGINT) handler.
The handler will be called with the
(sig, frame)signature just like a normal signal handler. def on_terminate(handler: Callable) ‑> None-
Register a SIGTERM handler when supported by the platform.
On Windows this is a no-op because SIGTERM is not always available.
def register(sig: int, handler: Callable) ‑> None-
Register a callback for a signal. Multiple callbacks per signal are supported (called in order).
def reset(sig: int) ‑> Nonedef reset_all() ‑> None
class Stdlib-
Expand source code
class Stdlib: """Facade providing convenient access to standard helpers. The `Stdlib` class is a small namespace bundling the `IOManager`, `SignalHandler`, `EnvManager` and `AliasStore` under a single importable symbol. It also exposes a `boot()` helper to load user config and set up default signal handlers. Example: from stdlib import Stdlib Stdlib.boot() Stdlib.io.write("Hello") """ io = IOManager signals = SignalHandler env = EnvManager aliases = AliasStore @classmethod def boot(cls) -> None: """Initialize stdlib: load config, set up default signals.""" cls.env.load_config() def _default_ctrl_c(sig, frame): cls.io.write("\n[Ctrl+C]") cls.signals.on_ctrl_c(_default_ctrl_c)Facade providing convenient access to standard helpers.
The
Stdlibclass is a small namespace bundling theIOManager,SignalHandler,EnvManagerandAliasStoreunder a single importable symbol. It also exposes aboot()helper to load user config and set up default signal handlers.Example
from stdlib import Stdlib Stdlib.boot() Stdlib.io.write("Hello")
Class variables
var aliases-
A lightweight alias table used by the shell.
Aliases map a single token to an expanded command string. Expansion is performed by
expand()which supports recursive alias substitution with a safety limit to avoid infinite loops. var env-
Environment and configuration helper for linux++.
EnvManagermaintains a merged view of the host environment and a local store used by the shell and applications. Local variables may shadow host environment keys and can optionally be exported toos.environso child processes inherit them.Responsibilities include PATH resolution, loading/saving a simple INI config (
.linuxpprc) and providing helpers such asusername()andhostname()used in prompt rendering. var io-
High-level I/O primitives used across linux++.
IOManagercentralises common I/O operations so higher-level code can work with text and files in a consistent way without repeatedly dealing with low-levelosfile descriptors. The class provides: - stdout/stderr helpers (write,error), - blocking line and full-stdin readers for pipelines, - low-level file operations usingos.open/os.readto avoid implicit buffering differences across platforms, - pipe helpers returning raw file descriptors for use withos.pipe(), - context managers for temporarily redirectingsys.stdin/sys.stdout.All methods use only standard library facilities so this module remains portable and easy to unit-test.
var signals-
A small, multi-callback signal dispatcher.
Python's
signal.signal()allows a single handler per signal; this helper enables multiple callbacks to be registered for the same signal and calls them in registration order. It also provides convenience methods for registering common handlers (e.g.on_ctrl_c). On Windows platform support is limited to the signals available there (commonly SIGINT and SIGTERM).
Static methods
def boot() ‑> None-
Initialize stdlib: load config, set up default signals.