The Console Display Manager (Go Port)
To run GoCDM, use gocdm [RCFILE].
GoCDM tries to source configuration files in the following order, and uses the first found configuration:
- [RCFILE] (direct input)
$HOME/.cdmrc$XDG_CONFIG_HOME/cdm/cdmrc/etc/cdmrc
To autostart gocdm when you log in your account, copy the content of /usr/share/doc/gocdm/profile.sh to the tail of your shell profile (~/.profile, etc.).
GoCDM can run in login-manager mode with native username/password prompts and PAM authentication.
Build and install the standard binary:
go build -o gocdm ./cmd/gocdm
sudo install -m 0755 gocdm /usr/local/bin/gocdmBuild and install the PAM-enabled binary:
go build -tags pam -o gocdm-pam ./cmd/gocdm
sudo install -m 0755 gocdm-pam /usr/local/bin/gocdmIn login mode, GoCDM authenticates credentials through PAM, prepares a sanitized session environment (HOME, SHELL, USER, LOGNAME, plus /etc/security/pam_env.conf), and drops privileges to the authenticated account before launching the selected session.
If you want GoCDM to start after a normal shell login, append this to ~/.profile (or ~/.bash_profile):
if [ -z "${DISPLAY:-}" ] && [ "$(tty)" = "/dev/tty1" ]; then
exec /usr/local/bin/gocdm
fiTo run GoCDM directly from tty1 under systemd, override getty@tty1.service:
sudo systemctl edit getty@tty1.serviceUse this override:
[Service]
ExecStart=
ExecStart=-/usr/local/bin/gocdm -login
StandardInput=tty
StandardOutput=tty
TTYPath=/dev/tty1
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yesThen reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart getty@tty1.serviceSee /etc/cdmrc for examples.
GoCDM now provides a c-shared entrypoint at cmd/gocdm-bindings for embedding core capabilities in native applications.
Build the shared library and generated header with:
go build -buildmode=c-shared -o libgocdm.so ./cmd/gocdm-bindingsThe generated header exposes:
GoCDMDefaultConfigJSON()GoCDMLoadConfigJSON(const char* path)GoCDMDiscoverSessionsJSON(const char* home_dir)GoCDMFreeCString(char* s)
Each function returns a heap-allocated JSON response envelope with this shape:
{"ok":true,"data":{...}}or on failure:
{"ok":false,"error":"..."}Always release returned strings with GoCDMFreeCString.
- Credentials are read only at interactive prompt time and sent directly to PAM for validation.
- On successful authentication, GoCDM derives a session environment from user identity (
/etc/passwd) and/etc/security/pam_env.confvalues. - Privilege transitions are explicit:
-loginuses PAM auth first, then drops privileges to the authenticated account before launching session executables. -loginshould be run from a real TTY (the binary rejects non-interactive launch unless-dry-runis used).
GoCDM requires a PAM-enabled build for -login mode:
go build -tags pam -o gocdm ./cmd/gocdmDefault PAM service is login (override with -pam-service). Typical stacks:
- Debian/Ubuntu:
loginservice in/etc/pam.d/login - Fedora/RHEL:
loginservice in/etc/pam.d/login - Arch Linux:
loginservice in/etc/pam.d/login
If PAM support is missing at build time, authentication fails with a clear error indicating to rebuild with -tags pam.
- Authentication prompt failure (stdin/stdout not usable): exits with error
Authentication prompt failed: .... - PAM authentication failure (wrong password/policy denial/service failure): exits with error
Authentication failed: .... - Non-interactive launch without
-dry-run: exits withgocdm must be launched from an interactive TTY. - If secure session environment assembly fails, GoCDM prints a warning and falls back to inherited environment.
| Platform | Support tier | -login mode |
X session launch path |
|---|---|---|---|
| Linux | Primary | Supported | Supported |
| FreeBSD / OpenBSD / NetBSD / DragonFly BSD | Secondary (best-effort) | Supported | Supported (best-effort) |
| Windows | Unsupported | Not supported | Not supported |
| Other platforms (e.g. macOS) | Unsupported | Not supported | Not supported |
GoCDM now emits explicit runtime errors for unsupported platform features:
-login is not supported on <GOOS> (support tier: unsupported)X session launch is not supported on <GOOS> (support tier: unsupported)
This keeps behavior intentional on non-Linux/BSD targets instead of failing later in the launch flow.
- Config path resolution (
RCFILE,$HOME/.cdmrc,$XDG_CONFIG_HOME/cdm/cdmrc,/etc/cdmrc) is implemented in that order. -menu,-dry-run, and-versionbehavior are implemented.-loginprompt/auth + privilege-transition flow is implemented.- Non-interactive startup is blocked unless
-dry-runis used.
- Console (
C) and Wayland (W) entries execute configured commands directly. - X (
X) supports both existing-session VT handoff (locktty) and new-session launch (startxpath).
- Deprecated config knobs now fail explicitly instead of behaving as silent/no-ops:
altstartx- non-default
cktimeoutin ConsoleKit path
- External X tooling is validated up-front with actionable errors (
chvt,startx,ck-launch-session). - Platform support policy is explicit (Linux primary, BSD secondary, other OS unsupported).
- Real-TTY/manual validation matrix for
locktty+xtty=keepacross init systems. - Additional
.desktopdiscovery parity expansion as new edge cases are identified.
- Manual real-TTY validation for
locktty+xtty=keep:- script:
scripts/manual/locktty_xtty_keep_test.sh - guide:
docs/LOCKTTY_XTTY_MANUAL_TEST.md
- script:
- CI parser edge-case checks for
.desktopdiscovery:- script:
scripts/ci/session_desktop_edgecases.sh - guide:
docs/SESSION_DISCOVERY_EDGECASES.md
- script:
For compositor/session startup guidance where Wayland behavior differs from X-session assumptions, see docs/WAYLAND_INTEGRATION.md.
GoCDM uses a native config parser (no shell-sourcing) for cdmrc values.
Validation rules:
- Array fields (
binlist,namelist,flaglist,serverargs) must use parenthesized shell-style list syntax. - If
namelistorflaglistis provided, its length must matchbinlistlength.
Config source precedence is enforced as:
-config <path>- positional config path (
gocdm <path>) - auto-discovery (
$HOME/.cdmrc,$XDG_CONFIG_HOME/cdm/cdmrc,/etc/cdmrc)
Providing both -config and a positional config path is treated as an error.
- Native Go CLI session dispatcher (
C/W/X) with config/state handling. - Native config parser with validation and explicit precedence rules.
- Login-manager mode with PAM-aware flow, privilege drop path, and failure-mode UX.
- X launch hardening (tool checks, explicit deprecation handling for unsupported legacy knobs).
- Platform support policy with explicit unsupported-platform UX.
- Real-TTY behavior validation across distributions/init systems (
locktty,xtty=keep) via manual script. - Deployment-specific Wayland compositor startup wrappers and distro integration details.
- Full runtime parity for deprecated legacy knobs (
altstartx, non-defaultcktimeout). - Non-Linux/BSD first-class support (other platforms remain unsupported/best-effort only).
See docs/PACKAGING.md for distro-oriented install guidance (standard and PAM-enabled builds).
See docs/TROUBLESHOOTING.md for common operational errors and remediation steps.
See docs/RELEASE_CHECKLIST.md for pre-release gates and tagging/changelog steps.
See examples/embedding/c/README.md for a minimal C embedding workflow using cmd/gocdm-bindings.