Platform Differences¶
Endo runs on Linux, macOS, and Windows. Most features work identically across platforms, but some low-level behaviors differ due to fundamental OS differences. This page documents what Windows users should know.
Signal Handling¶
POSIX (Linux, macOS)¶
On POSIX systems, Endo uses standard Unix signals for process lifecycle management:
- SIGCHLD -- notification when a child process exits or stops
- SIGTSTP -- triggered by Ctrl+Z to suspend the foreground process
- SIGCONT -- resumes a stopped process
- SIGINT -- triggered by Ctrl+C to interrupt the foreground process
- SIGTERM / SIGKILL -- used to terminate processes
On Linux, signals are received via signalfd for efficient event-loop integration. On macOS/BSD, traditional signal handlers set atomic flags that the main loop polls.
Windows¶
Windows does not have POSIX signals. Endo uses native Windows APIs to achieve equivalent behavior:
| POSIX Signal | Windows Equivalent |
|---|---|
SIGINT | GenerateConsoleCtrlEvent(CTRL_C_EVENT, ...) |
SIGTERM | TerminateProcess() |
SIGKILL | TerminateProcess() |
SIGTSTP | SuspendThread() on all threads of the target process |
SIGCONT | ResumeThread() on all threads of the target process |
SIGCHLD | Polling via WaitForSingleObject / WaitForMultipleObjects |
Child process termination is detected by waiting on the process handle rather than receiving a signal. The shell polls for child state changes using the Windows wait APIs.
Shell Suspension (Ctrl+Z)¶
POSIX¶
On POSIX systems, pressing Ctrl+Z sends SIGTSTP to the foreground process group. This can suspend both child processes and the shell itself. When suspended, the parent shell (e.g. Bash) takes back control. Typing fg in the parent shell resumes Endo.
Windows¶
On Windows, Ctrl+Z cannot suspend the Endo shell itself. This is because:
- Windows has no
SIGTSTPsignal. - Windows has no process groups in the POSIX sense -- there is no mechanism for a parent terminal to "stop" and later "continue" an arbitrary process the way Unix shells do.
- There is no equivalent of
tcsetpgrp()for transferring terminal foreground control.
What works:
- Ctrl+C -- interrupts the foreground child process
- bg -- resumes a suspended job in the background
- fg -- brings a background job to the foreground
- Job management -- suspending and resuming child processes with
SuspendThread/ResumeThread
What does not work:
- Suspending the Endo shell itself with Ctrl+Z
Workarounds:
- Open multiple terminal tabs or windows instead of suspending and resuming the shell.
- Use the built-in job control (
bg,fg,jobs) to manage child processes within Endo.
Job Control¶
Job control (background processes, bg, fg, jobs) works on both platforms, but the underlying implementation differs.
POSIX¶
- Uses process groups (
setpgid,tcsetpgrp) to manage foreground/background jobs. - Sends
SIGTSTPto stop a process group andSIGCONTto resume it. - The terminal driver handles foreground group switching.
Windows¶
- Process groups are tracked internally by Endo using a map of group membership.
- Suspension is implemented by enumerating all threads of a process (
CreateToolhelp32Snapshot) and callingSuspendThreadon each one. - Resumption calls
ResumeThreadon each thread. - There is no terminal foreground group concept;
setForegroundPgrpandgetForegroundPgrpare no-ops that return the current process ID.
These differences are transparent to the user -- bg, fg, and jobs commands work the same way on both platforms.
Process Substitution¶
Process substitution (<(command) and >(command)) is implemented on POSIX but not yet available on Windows.
POSIX¶
On Linux, process substitution uses /dev/fd/<n> or /proc/self/fd/<n> paths to expose a pipe as a file path. The shell forks a child process to run the substituted command, connects it to a pipe, and passes the file descriptor path to the parent command.
# Compare output of two commands
diff <(ls dir1) <(ls dir2)
# Use command output as input file
sort <(cat file1 file2)
Windows¶
Process substitution is not yet implemented on Windows. Attempting to use <(...) or >(...) will produce an error message:
A future implementation may use Windows named pipes (CreateNamedPipe) to provide equivalent functionality. Named pipes on Windows can be opened by path (e.g. \\.\pipe\endo-procsubst-<id>) and would allow child processes to read from or write to the pipe as if it were a file.
Tilde Expansion (~username)¶
Tilde expansion for the current user (~ and ~/path) works on all platforms.
Expansion of other users' home directories (~username) differs in implementation:
POSIX¶
Uses getpwnam() to look up the user's home directory from the system password database. This provides an authoritative answer for any valid local user.
Windows¶
Windows has no equivalent of /etc/passwd or getpwnam(). Endo uses a heuristic approach:
- Reads the current user's profile path from the
USERPROFILEenvironment variable (e.g.C:\Users\alice). - Derives the parent directory (
C:\Users). - Checks whether
C:\Users\<username>exists on disk. - If found, uses that path. Otherwise, returns the literal
~usernameunexpanded.
This heuristic works well when all user profiles reside under the same parent directory, which is the default Windows configuration. It will not resolve users whose profiles are stored in non-standard locations.
Environment Variables¶
Case Sensitivity¶
Environment variable names are case-sensitive on POSIX and case-insensitive on Windows. Endo's Windows environment provider uses case-insensitive comparison for lookups, matching native Windows behavior.
Home Directory¶
| Variable | POSIX | Windows |
|---|---|---|
| Home directory | $HOME | $USERPROFILE (Endo also sets $HOME) |
| Config directory | $XDG_CONFIG_HOME or ~/.config | $APPDATA |
Process Creation¶
POSIX¶
Uses fork() + execve() for process creation. Child processes inherit open file descriptors. Process groups are set with setpgid().
Windows¶
Uses CreateProcessW() with explicit handle inheritance via STARTUPINFOW. The CREATE_NEW_PROCESS_GROUP flag is used when the shell needs to manage a job as a separate group. Command-line arguments are quoted according to Microsoft's C/C++ parameter parsing rules.
File Paths¶
Endo normalizes path handling across platforms, but some differences are visible:
| Aspect | POSIX | Windows |
|---|---|---|
| Separator | / | \ (but / also works) |
| Root | / | C:\ (or other drive letter) |
| Null device | /dev/null | NUL |
| Path length limit | ~4096 bytes | ~260 characters (32,767 with long path support) |
Endo accepts forward slashes in paths on Windows for convenience.
Summary¶
| Feature | Linux / macOS | Windows |
|---|---|---|
Shell pipes (\|) | Full support | Full support |
Forward pipes (\|>) | Full support | Full support |
Job control (bg, fg, jobs) | Full support | Full support (thread-based) |
| Ctrl+C (interrupt) | Full support | Full support |
| Ctrl+Z (suspend shell) | Full support | Not supported |
| Process substitution | Full support | Not yet implemented |
Tilde expansion (~) | Full support | Full support |
Tilde expansion (~user) | Full support | Heuristic-based |
| Signal handling | Native signals | Windows API equivalents |
| Tab completion | Full support | Full support |
| Syntax highlighting | Full support | Full support |