5 Commits

Author SHA1 Message Date
978aaad199 chore: misc (#100) (this makes 2.0.0)
Co-authored-by: grialion <48643945+grialion@users.noreply.github.com>

- Fix license ambiguity (#88)
  - just the only/or-later ambiguity point, not adding SPDX identifyiers unless more people request it
- Better document kmscon (#91)
- Make 2.0.0 already to close #86
- Add a changelog
- Add packagers info (acutally just add them to install guide)
- Add AUR service packages (I'll take care of systemd and dinit, let others package the rest and leave systemd open for someone who actually uses it in docs)
- Make sure all makefile installs to `/usr/local` by default
- Simplify Makefile complexity by several orders
2026-01-20 23:33:28 +01:00
9cf5297205 fix: building with -flto=auto (#102)
I need this to finish the AUR packages at #100.

It probably also broke the current lidm-git package
2026-01-20 22:29:58 +01:00
7e7a297e2e feat: support Xorg & better auth logic (#80)
Co-authored-by: grialion <48643945+grialion@users.noreply.github.com>
2026-01-19 21:17:45 +01:00
Martin Bogdanov
d65bd7a8ee feat: get sessions from /usr/local/share/{x,wayland-}sessions (#99)
Co-authored-by: javalsai <jvssxxi@gmail.com>
2026-01-19 20:35:44 +01:00
Martin Bogdanov
728611aa19 fix: systemd service install recipe & systemd service restart (#96) 2026-01-16 16:18:13 +01:00
33 changed files with 519 additions and 276 deletions

2
.gitignore vendored
View File

@@ -8,5 +8,3 @@ valgrind-out.txt
# nix build result # nix build result
result result
include/version.h

10
CHANGELOG.md Normal file
View File

@@ -0,0 +1,10 @@
<!-- Unspecified dates shall be in CET/CEST -->
<!-- Add only very relevant changes, bottom to top -->
<!-- By "very relevant" I mean big features or something manual packagers should know, like leftover files -->
<!-- Once a release would be opened, group the last bunch of dangling changes, add release version as header and its date -->
- Most stuff (most of `/etc` being a notable exception) now installs to `/usr/local` by default, check [`docs/PACKAGERS.md`](./docs/PACKAGERS.md).
- Added a changelog.
- Finally add proper (experimental) xorg support.
- Systemd service install path changed to `/usr/local/lib/systemd`, there could be a leftover file at `/etc/systemd/system/lidm.service`.

140
Makefile
View File

@@ -1,41 +1,32 @@
VERSION = 1.2.3 VERSION = 2.0.0
.DEFAULT_GOAL := lidm .DEFAULT_GOAL := lidm
CDIR=src CDIR = src
LDIR=lib LDIR = lib
IDIR=include IDIR = include
ODIR=dist ODIR = dist
PREFIX=/usr PREFIX = /usr/local
CC?=gcc INFO_GIT_REV ?= $(shell git describe --long --tags --always || echo '?')
CFLAGS?=-O3 -Wall -Wextra -fdata-sections -ffunction-sections INFO_BUILD_TS ?= $(shell date +%s)
CFLAGS ?= -O3 -Wall -Wextra -fdata-sections -ffunction-sections
# C PreProcessor flags, not C Plus Plus # C PreProcessor flags, not C Plus Plus
CPPFLAGS?= CPPFLAGS ?=
ALLFLAGS=$(CFLAGS) $(CPPFLAGS) -I$(IDIR) _DFLAGS?= \
LDFLAGS?=-Wl,--gc-sections -DLIDM_VERSION=\"$(VERSION)\" \
-DLIDM_GIT_REV=\"$(INFO_GIT_REV)\" \
-DLIDM_BUILD_TS=$(INFO_BUILD_TS)
ALLFLAGS = $(_DFLAGS) $(CFLAGS) $(CPPFLAGS) -I$(IDIR)
LDFLAGS ?= -Wl,--gc-sections
LIBS=-lpam LIBS = -lpam
_DEPS = version.h log.h util.h ui.h ui_state.h config.h pam.h desktop.h desktop_exec.h auth.h ofield.h efield.h keys.h users.h sessions.h chvt.h macros.h launch_state.h # includes all headers in `$(IDIR)` and compiles everything in `$(CDIR)`
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) DEPS = $(wildcard $(IDIR)/*.h)
_SOURCES = $(notdir $(wildcard $(CDIR)/*.c))
_OBJ = main.o log.o util.o ui.o ui_state.o config.o pam.o desktop.o desktop_exec.o auth.o ofield.o efield.o users.o sessions.o chvt.o launch_state.o OBJ = $(patsubst %.c,$(ODIR)/%.o,$(_SOURCES))
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
INFO_GIT_REV?=$$(git describe --long --tags --always || echo '?')
INFO_BUILD_TS?=$$(date +%s)
$(IDIR)/version.h: Makefile
@tmp=$$(mktemp); \
printf '' > $$tmp; \
echo '#define LIDM_VERSION "'$(VERSION)'"' >> $$tmp; \
echo '#define LIDM_GIT_REV "'$(INFO_GIT_REV)'"' >> $$tmp; \
echo '#define LIDM_BUILD_TS '$(INFO_BUILD_TS) >> $$tmp; \
if ! cmp -s $$tmp $@; then \
mv $$tmp $@; \
fi; \
rm -f $$tmp;
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS) $(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
@mkdir -p $(ODIR) @mkdir -p $(ODIR)
@@ -47,7 +38,6 @@ lidm: $(OBJ)
clean: clean:
rm -f $(ODIR)/*.o lidm rm -f $(ODIR)/*.o lidm
# Copy lidm to ${DESTDIR}${PREFIX}/bin (/usr/bin)
install: lidm install: lidm
mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${PREFIX}/share/man/man{1,5} mkdir -p ${DESTDIR}${PREFIX}/bin ${DESTDIR}${PREFIX}/share/man/man{1,5}
install -Dm755 ./lidm ${DESTDIR}${PREFIX}/bin/ install -Dm755 ./lidm ${DESTDIR}${PREFIX}/bin/
@@ -55,83 +45,11 @@ install: lidm
install -Dm644 ./assets/man/lidm.1 ${DESTDIR}${PREFIX}/share/man/man1/ install -Dm644 ./assets/man/lidm.1 ${DESTDIR}${PREFIX}/share/man/man1/
install -Dm644 ./assets/man/lidm-config.5 ${DESTDIR}${PREFIX}/share/man/man5/ install -Dm644 ./assets/man/lidm-config.5 ${DESTDIR}${PREFIX}/share/man/man5/
uninstall: uninstall: uninstall-service
rm -rf ${DESTDIR}${PREFIX}/bin/lidm ${DESTDIR}/etc/lidm.ini rm -rf ${DESTDIR}${PREFIX}/bin/lidm ${DESTDIR}/etc/lidm.ini
rm -rf ${DESTDIR}/usr/share/man/man{1/lidm.1,5/lidm-config.5}.gz rm -rf ${DESTDIR}${PREFIX}/share/man/man{1/lidm.1,5/lidm-config.5}.gz
rm -rf ${DESTDIR}/usr/local/lib/systemd/system/lidm.service ${DESTDIR}/etc/dinit.d/lidm ${DESTDIR}/etc/runit/sv/lidm
install-service: include services.mk
@if command -v systemctl &> /dev/null; then \
make install-service-systemd; \
elif command -v dinitctl &> /dev/null; then \
make install-service-dinit; \
elif command -v sv &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-runit; \
elif [ -d /etc/runit/sv ]; then \
make install-service-runit-etc; \
else \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
elif command -v rc-update &> /dev/null; then \
make install-service-openrc; \
elif command -v s6-service &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-s6; \
elif [ -d /etc/r6nit/sv ]; then \
make install-service-s6-etc; \
else \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
else \
printf '\033[1;31m%s\033[0m\n' "Unknown init system, skipping service install..." >&2; \
fi
install-service-systemd:
install -m644 ./assets/services/systemd.service ${DESTDIR}/usr/local/lib/systemd/system/lidm.service
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'systemctl enable lidm'"
install-service-dinit:
install -m644 ./assets/services/dinit ${DESTDIR}/etc/dinit.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'dinitctl enable lidm'"
install-service-runit:
@if [ ! -e /etc/sv ] && [ -d /etc/runit/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/runit/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/sv/lidm /var/service' or your distro equivalent"
install-service-runit-etc:
@if [ ! -e /etc/runit/sv ] && [ -d /etc/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/runit/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/runit/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/runit/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/runit/sv/lidm /run/runit/service' or your distro equivalent"
install-service-openrc:
install -m755 ./assets/services/openrc ${DESTDIR}/etc/init.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'rc-update add lidm'"
install-service-s6:
@if [ ! -e /etc/sv ] && [ -d /etc/s6/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/s6/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
install-service-s6-etc:
@if [ ! -e /etc/s6/sv ] && [ -d /etc/sv ] && [ -z "$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/s6/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/s6/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/s6/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
pre-commit: pre-commit:
codespell codespell
@@ -147,13 +65,5 @@ print-version:
.PHONY: clean \ .PHONY: clean \
install uninstall \ install uninstall \
install-service \
install-service-s6 \
install-service-s6-etc \
install-service-dinit \
install-service-runit \
install-service-runit-etc \
install-service-openrc \
install-service-systemd \
pre-commit \ pre-commit \
print-version print-version

View File

@@ -15,12 +15,16 @@ LiDM is like any [Display Manager](https://en.wikipedia.org/wiki/X_display_manag
shown as in a featured terminal emulator, actual linux console doesn't support as much color and decorations shown as in a featured terminal emulator, actual linux console doesn't support as much color and decorations
</i></summary> </i></summary>
If you want to add fancy color and font support to your TTYs you can wrap lidm in [`kmscon`](https://wiki.archlinux.org/title/KMSCON). (edit appropriate service files). e.g: If you want to add fancy color and font support to your TTYs you can try wrapping lidm in [`kmscon`](https://wiki.archlinux.org/title/KMSCON). (edit appropriate service files). e.g:
```sh ```sh
kmscon -l --vt /dev/tty7 --font-name "Cascadia Code" -- /usr/bin/lidm kmscon -l --vt /dev/tty7 --font-name "Cascadia Code" -- /usr/bin/lidm
``` ```
Kmscon is NOT officially supported so you are on your own when trying this, [according to the arch wiki](https://wiki.archlinux.org/title/KMSCON#Window_managers_cannot_be_started_from_KMS_console) it's not possible to start window managers if you do this.
But [according to farouk](https://github.com/javalsai/lidm/issues/91#issuecomment-3708503568) you can make it work if you tell kmscon to work in `no-drm` mode. There's still input grabbing issues which cause <kbd><kbd>Ctrl</kbd> + <kbd>C</kbd></kbd> to kill lidm, they are likely fixable though.
</details></blockquote> </details></blockquote>
> _however, all colors and strings are fully customizable_ > _however, all colors and strings are fully customizable_
@@ -29,7 +33,7 @@ kmscon -l --vt /dev/tty7 --font-name "Cascadia Code" -- /usr/bin/lidm
- Simple as C, meant to depend only on standard libc and basic unix system headers. - Simple as C, meant to depend only on standard libc and basic unix system headers.
- Fully customizable: ALL strings, colors (with its ANSI keys) and most behavior. - Fully customizable: ALL strings, colors (with its ANSI keys) and most behavior.
- Xorg[\*](https://github.com/javalsai/lidm/issues/79) and wayland sessions, while supporting the default user shell (if enabled in config) - Experimental Xorg support[\*](https://github.com/javalsai/lidm/pull/80?#issuecomment-3764073217) and wayland sessions, while supporting the default user shell (if enabled in config)
- Init agnostinc (systemd, dinit, runit, openrc and s6). - Init agnostinc (systemd, dinit, runit, openrc and s6).
- Supports [fido yubikeys](./docs/yubikey.md) (via pam_u2f). - Supports [fido yubikeys](./docs/yubikey.md) (via pam_u2f).
@@ -44,6 +48,7 @@ kmscon -l --vt /dev/tty7 --font-name "Cascadia Code" -- /usr/bin/lidm
- [Configuring](#configuring) - [Configuring](#configuring)
- [PAM](#pam) - [PAM](#pam)
- [Contributing](#contributing) - [Contributing](#contributing)
- [License](#license)
- [Inspiration](#inspiration) - [Inspiration](#inspiration)
- [Contributors](#contributors) - [Contributors](#contributors)
@@ -117,6 +122,10 @@ When the env variable is empty it defaults to the `login` PAM service or whateve
If you want to contribute check the [contribution guide](docs/CONTRIBUTING.md). If you want to contribute check the [contribution guide](docs/CONTRIBUTING.md).
# License
This project is licensed under the GNU General Public License v3.0 **only**.
# Inspiration # Inspiration
This project was started after facing some issues building [ly](https://github.com/fairyglade/ly) on an ancient laptop, the UI is heavily inspired by it. This project was started after facing some issues building [ly](https://github.com/fairyglade/ly) on an ancient laptop, the UI is heavily inspired by it.

View File

@@ -1,15 +1,16 @@
pkgbase = lidm-bin pkgbase = lidm-bin
pkgdesc = A fully colorful customizable TUI display manager made in C. (release binary) pkgdesc = A fully colorful customizable TUI display manager made in C. (release binary)
pkgver = 1.2.3 pkgver = 1.2.3
pkgrel = 3 pkgrel = 4
url = https://github.com/javalsai/lidm url = https://github.com/javalsai/lidm
arch = x86_64 arch = x86_64
arch = i686 arch = i686
arch = aarch64 arch = aarch64
arch = armv7h arch = armv7h
arch = riscv64 arch = riscv64
license = GPL license = GPL-3.0-only
depends = libpam.so depends = libpam.so
depends = lidm-service
provides = lidm provides = lidm
conflicts = lidm conflicts = lidm
source = lidm-default-theme-1.2.3.ini::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/themes/default.ini source = lidm-default-theme-1.2.3.ini::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/themes/default.ini

View File

@@ -2,12 +2,12 @@
# Maintainer: javalsai <javalsai@proton.me> # Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-bin pkgname=lidm-bin
pkgver=1.2.3 pkgver=1.2.3
pkgrel=3 pkgrel=4
depends=('libpam.so') depends=('libpam.so' 'lidm-service')
pkgdesc="A fully colorful customizable TUI display manager made in C. (release binary)" pkgdesc="A fully colorful customizable TUI display manager made in C. (release binary)"
arch=('x86_64' 'i686' 'aarch64' 'armv7h' 'riscv64') arch=('x86_64' 'i686' 'aarch64' 'armv7h' 'riscv64')
url="https://github.com/javalsai/lidm" url="https://github.com/javalsai/lidm"
license=('GPL') license=('GPL-3.0-only')
provides=('lidm') provides=('lidm')
conflicts=('lidm') conflicts=('lidm')
source=( source=(

View File

@@ -0,0 +1,12 @@
pkgbase = lidm-dinit
pkgdesc = A fully colorful customizable TUI display manager made in C. (dinit service files)
pkgver = 1.2.3
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = any
license = GPL-3.0-only
provides = lidm-service
source = lidm-dinit-1.2.3-dinit::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/assets/services/dinit
sha256sums = 185cd76c1d29ddc73cf96be999f13278a427bb80aa9169f25f30673ad2de3770
pkgname = lidm-dinit

3
assets/pkg/aur/lidm-dinit/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
*
!PKGBUILD
!.SRCINFO

View File

@@ -0,0 +1,17 @@
# shellcheck disable=SC2034,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-dinit
pkgver=1.2.3
pkgrel=1
pkgdesc="A fully colorful customizable TUI display manager made in C. (dinit service files)"
provides=('lidm-service')
arch=('any')
url="https://github.com/javalsai/lidm"
license=('GPL-3.0-only')
source=("${pkgname}-${pkgver}-dinit::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/assets/services/dinit")
sha256sums=('185cd76c1d29ddc73cf96be999f13278a427bb80aa9169f25f30673ad2de3770')
package() {
cd "$srcdir"
install -Dm0644 "${pkgname}-${pkgver}-dinit" "$pkgdir/etc/dinit.d/lidm"
}

View File

@@ -1,12 +1,13 @@
pkgbase = lidm-git pkgbase = lidm-git
pkgdesc = A fully colorful customizable TUI display manager made in C. (last git commit) pkgdesc = A fully colorful customizable TUI display manager made in C. (last git commit)
pkgver = 1.2.3.r3.g363deea pkgver = 1.2.3.r12.g7e7a297
pkgrel = 3 pkgrel = 1
url = https://github.com/javalsai/lidm url = https://github.com/javalsai/lidm
arch = any arch = any
license = GPL license = GPL-3.0-only
makedepends = git makedepends = git
depends = pam depends = pam
depends = lidm-service
provides = lidm provides = lidm
conflicts = lidm conflicts = lidm
source = lidm::git+https://github.com/javalsai/lidm source = lidm::git+https://github.com/javalsai/lidm

View File

@@ -1,14 +1,14 @@
# shellcheck disable=SC2034,SC2154,SC2164 # shellcheck disable=SC2034,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me> # Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-git pkgname=lidm-git
pkgver=1.2.3.r3.g363deea pkgver=1.2.3.r13.g9cf5297
pkgrel=3 pkgrel=1
depends=('pam') depends=('pam' 'lidm-service')
makedepends=('git') makedepends=('git')
pkgdesc="A fully colorful customizable TUI display manager made in C. (last git commit)" pkgdesc="A fully colorful customizable TUI display manager made in C. (last git commit)"
arch=('any') arch=('any')
url="https://github.com/javalsai/lidm" url="https://github.com/javalsai/lidm"
license=('GPL') license=('GPL-3.0-only')
provides=('lidm') provides=('lidm')
conflicts=('lidm') conflicts=('lidm')
source=("lidm::git+https://github.com/javalsai/lidm") source=("lidm::git+https://github.com/javalsai/lidm")

View File

@@ -0,0 +1,12 @@
pkgbase = lidm-systemd
pkgdesc = A fully colorful customizable TUI display manager made in C. (systemd service files)
pkgver = 1.2.3
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = any
license = GPL-3.0-only
provides = lidm-service
source = lidm-systemd-1.2.3-systemd::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/assets/services/systemd.service
sha256sums = e63464441a97102194994adc82159871ccd3f23d5e97224f21a460e4296364cc
pkgname = lidm-systemd

View File

@@ -0,0 +1,3 @@
*
!PKGBUILD
!.SRCINFO

View File

@@ -0,0 +1,17 @@
# shellcheck disable=SC2034,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-systemd
pkgver=1.2.3
pkgrel=1
pkgdesc="A fully colorful customizable TUI display manager made in C. (systemd service files)"
provides=('lidm-service')
arch=('any')
url="https://github.com/javalsai/lidm"
license=('GPL-3.0-only')
source=("${pkgname}-${pkgver}-systemd::https://raw.githubusercontent.com/javalsai/lidm/v1.2.3/assets/services/systemd.service")
sha256sums=('e63464441a97102194994adc82159871ccd3f23d5e97224f21a460e4296364cc')
package() {
cd "$srcdir"
install -Dm0644 "${pkgname}-${pkgver}-systemd" "$pkgdir/usr/lib/systemd/system/lidm.service"
}

View File

@@ -1,11 +1,12 @@
pkgbase = lidm pkgbase = lidm
pkgdesc = A fully colorful customizable TUI display manager made in C. (build latest tag) pkgdesc = A fully colorful customizable TUI display manager made in C. (build latest tag)
pkgver = 1.2.3 pkgver = 1.2.3
pkgrel = 3 pkgrel = 5
url = https://github.com/javalsai/lidm url = https://github.com/javalsai/lidm
arch = any arch = any
license = GPL license = GPL-3.0-only
depends = pam depends = pam
depends = lidm-service
source = lidm-1.2.3.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v1.2.3.tar.gz source = lidm-1.2.3.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v1.2.3.tar.gz
sha256sums = 1ce414b510c5bbc3e32ea882f915b4d3958cb82eb1fbb5cf33e62f69c844bf93 sha256sums = 1ce414b510c5bbc3e32ea882f915b4d3958cb82eb1fbb5cf33e62f69c844bf93

View File

@@ -2,13 +2,13 @@
# Maintainer: javalsai <javalsai@proton.me> # Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm pkgname=lidm
pkgver=1.2.3 pkgver=1.2.3
pkgrel=3 pkgrel=5
depends=('pam') depends=('pam' 'lidm-service')
makedepends=() makedepends=()
pkgdesc="A fully colorful customizable TUI display manager made in C. (build latest tag)" pkgdesc="A fully colorful customizable TUI display manager made in C. (build latest tag)"
arch=('any') arch=('any')
url="https://github.com/javalsai/lidm" url="https://github.com/javalsai/lidm"
license=('GPL') license=('GPL-3.0-only')
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v$pkgver.tar.gz") source=("${pkgname}-${pkgver}.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v$pkgver.tar.gz")
sha256sums=('1ce414b510c5bbc3e32ea882f915b4d3958cb82eb1fbb5cf33e62f69c844bf93') sha256sums=('1ce414b510c5bbc3e32ea882f915b4d3958cb82eb1fbb5cf33e62f69c844bf93')

View File

@@ -5,7 +5,7 @@ MYSELF=$(realpath "$0")
MYDIR=$(dirname "$MYSELF") MYDIR=$(dirname "$MYSELF")
cd "$MYDIR" cd "$MYDIR"
typeset -a pkgs=(lidm{,-git,-bin}) typeset -a pkgs=(lidm{,-git,-bin,-systemd,-dinit})
for pkg in "${pkgs[@]}"; do for pkg in "${pkgs[@]}"; do
printf "\x1b[mEntering '%s'\x1b[0m\n" "$pkg" printf "\x1b[mEntering '%s'\x1b[0m\n" "$pkg"

View File

@@ -5,7 +5,7 @@ MYSELF=$(realpath "$0")
MYDIR=$(dirname "$MYSELF") MYDIR=$(dirname "$MYSELF")
cd "$MYDIR" cd "$MYDIR"
typeset -a pkgs=(lidm{,-git,-bin}) typeset -a pkgs=(lidm{,-git,-bin,-systemd,-dinit})
for pkg in "${pkgs[@]}"; do for pkg in "${pkgs[@]}"; do
printf "\x1b[mEntering '%s'\x1b[0m\n" "$pkg" printf "\x1b[mEntering '%s'\x1b[0m\n" "$pkg"

View File

@@ -11,7 +11,7 @@ fi
version="$1" version="$1"
printf "\x1b[34mINF: Using '%s' version\x1b[0m\n" "$version" printf "\x1b[34mINF: Using '%s' version\x1b[0m\n" "$version"
for pkg in "$MYDIR"/lidm{,-bin}/; do for pkg in "$MYDIR"/lidm{,-bin,-systemd,-dinit}/; do
cd "$pkg" cd "$pkg"
printf "\x1b[1mEntering '%s'\x1b[0m\n" "$pkg" printf "\x1b[1mEntering '%s'\x1b[0m\n" "$pkg"
sed -i "s/pkgver=.*/pkgver=$1/" PKGBUILD sed -i "s/pkgver=.*/pkgver=$1/" PKGBUILD

View File

@@ -2,18 +2,17 @@
This folder contains the files necessary to set up lidm on start up for the supported init systems, all of them are configured for tty7. This folder contains the files necessary to set up lidm on start up for the supported init systems, all of them are configured for tty7.
If you're using lidm from a packaged source, this should be included with the package. Only read this for manual installations, if you are packaging or if your package exceptionally doesn't include them.
If you don't know what a init system is, you're certainly using `systemd`. If you don't know what a init system is, you're certainly using `systemd`.
There's make scripts to automatically copy the service files to the proper locations, you just have to run `make install-service-$INIT` (or `make install-service-$INIT-etc`). `make install-service` will attempt to detect the init system in use and install for it. There's make scripts to automatically copy the service files to the proper locations, you just have to run `make install-service-$INIT` (or `make install-service-$INIT-etc`). `make install-service` will attempt to detect the init system in use and install for it.
The manual steps for installation are: The manual steps for installation are:
> [!IMPORTANT]
> If you think this should be packaged too, there's [a discussion](https://github.com/javalsai/lidm/discussions/39) to talk about this.
## Systemd ## Systemd
- Copy `systemd.service` to `/usr/local/lib/systemd/system/lidm.service` (if the directory doesn't exist, create it first) - Copy `systemd.service` to `/usr/local/lib/systemd/system/lidm.service` (if the directory doesn't exist, create it first) or `/usr/lib/systemd/system/lidm.service` (if you wish to install along your system files).
- To enable it you can run `systemctl enable lidm` - To enable it you can run `systemctl enable lidm`
## Dinit ## Dinit
@@ -23,8 +22,10 @@ The manual steps for installation are:
## Runit ## Runit
- Copy `runit/` to `/etc/runit/sv/lidm/` Your runit service path can be either `/etc/runit/sv` or `/etc/sv`.
- Add the service with `ln -s /etc/runit/sv/lidm /run/runit/service`
- Copy `runit/` to `runit-path/lidm/`
- Add the service with `ln -s runit-path/lidm /run/runit/service`
- And to enable it `sv enable lidm` - And to enable it `sv enable lidm`
## OpenRC ## OpenRC
@@ -34,7 +35,9 @@ The manual steps for installation are:
## S6 ## S6
- Copy `s6/` to `/etc/s6/sv/lidm/` Your S6 service path can be either `/etc/s6/sv` or `/etc/sv`.
- Copy `s6/` to `s6-path/lidm/`
- Add the service with `s6-service add default lidm` - Add the service with `s6-service add default lidm`
- Reload the database with `s6-db-reload` (you might have to run this every time the service file changes) - Reload the database with `s6-db-reload` (you might have to run this every time the service file changes)

View File

@@ -11,6 +11,7 @@ StandardError=tty
TTYPath=/dev/tty7 TTYPath=/dev/tty7
TTYReset=yes TTYReset=yes
TTYVHangup=yes TTYVHangup=yes
Restart=always
[Install] [Install]
Alias=display-manager.service Alias=display-manager.service

View File

@@ -1,63 +1,73 @@
# Table of Contents # Table of Contents
- [Packages](#packages)
- [Void Linux](#void-linux)
- [Fedora](#fedora)
- [AUR](#aur)
- [Nix Flake](#nix-flake)
- [Nix Module](#nix-module)
- [Installing from Source](#installing-from-source) - [Installing from Source](#installing-from-source)
- [AUR](#aur)
- [Nix Flake](#nix-flake)
- [Nix Module](#nix-module)
> [!CAUTION] # Packages
> I encourage you to read the manual installation steps to understand what will get installed in your computer by this package.
# Installing from Source Lidm relies on its community to package lidm for distributions and make the installation easier for everyone. Please raise any issues on the packages themselves and not the source repository.
Firstly, you'll need to build the package, this also includes man pages, default config, themes and other files you might need. If you packaged lidm for any distribution not listed here or keep your own version of an inactive package, feel free to contact me to be added here. (could be a GitHub discussion or an email if you don't use GitHub)
To build it you only need to have some basic packages (should come pre-installed in almost all distros): `make`, `gcc` or another `gcc`ish compiler, and libpam headers. If it builds, it surely works anyways. These packages just install lidm, once installed you have to enable it. It depends on your init system, but if you're using systemd (most likely), first find your currently active display manager (if any, examples are `sddm`, `gdm`, `ly`) and disable it:
```sh ```sh
git clone https://github.com/javalsai/lidm.git systemctl disable <display manager name here>
cd lidm
make # 👍
``` ```
> [!NOTE] And then enable lidm:
> There's pre-built binaries on the [releases tab](https://github.com/javalsai/lidm/releases) too.
Then you can install the files onto your filesystem with:
```sh ```sh
make install systemctl enable lidm
``` ```
And additionally, to install service files (start-up behavior). <sup>[more docs](../assets/services/README.md)</sup> Lidm now should show on the next boot!
If you are on a TTY and don't wish to reboot, you should be able to use `--now` with both commands. It's likely to kill your current desktop environment if it was launched from it.
## Void Linux
Lidm can be installed from the official Void Linux packages:
```sh ```sh
# automatically detects your init system xbps-install lidm
# and install service file (for tty7)
make install-service
# or if you don't like autodetection
make install-service-systemd # systemd
make install-service-dinit # dinit
make install-service-runit # runit (/etc/sv)
make install-service-runit-etc # runit (/etc/runit/sv)
make install-service-openrc # openrc
make install-service-s6 # s6 (/etc/sv)
make install-service-s6-etc # s6 (/etc/s6/sv)
# For runit and s6, some distros (e.g. Artix) like to put it in /etc/<init>/sv
# to better isolate their packages while other distros (e.g. Void) just put it
# in /etc/sv
``` ```
# AUR To enable the service that starts on boot:
[AUR packages](https://aur.archlinux.org/packages?K=lidm&SeB=n) will automatically install most files. ```sh
ln -s /etc/sv/lidm /var/service/
```
> [!CAUTION] It is recommended to disable any other display managers that are still enabled:
> [service files](../assets/pkg/aur#services) have to be manually installed by now.
# Nix Flake ```sh
touch /etc/sv/lightdm/down # replace lightdm with your previous display manager (e.g., sddm, gdm)
```
## Fedora
Thanks to @KernelFreeze there's a COPR repo available at <https://copr.fedorainfracloud.org/coprs/celestelove/lidm/> to install lidm. (<https://github.com/javalsai/lidm/discussions/92>)
## AUR
There are several [AUR packages](https://aur.archlinux.org/packages?K=lidm&SeB=n) for most things. You only need to install one of the following:
* `lidm`
* `lidm-bin`
* `lidm-git`
Each of those depend on `lidm-service` which is provided by `lidm-systemd` and `lidm-dinit` (you'll have to pick one). I maintain both but I'm open to anyone that actually uses systemd to take the first one.
There's packagers needed for openrc, s6 and runit. If you know how to make AUR packages, feel free to take any of those if you use each init system.
## Nix Flake
You can install by doing You can install by doing
@@ -72,9 +82,9 @@ nix run github:javalsai/lidm
``` ```
> [!CAUTION] > [!CAUTION]
> This doesn't include [service files](../assets/pkg/aur#services) neither > This doesn't include [service files](../assets/pkg/aur#services)
# Nix Module ## Nix Module
<details> <details>
<summary>Sidenote</summary> <summary>Sidenote</summary>
@@ -126,3 +136,47 @@ with config.lidm.keysEnum; {
> [!NOTE] > [!NOTE]
> [service files](../assets/pkg/aur#services) **are** included and enabled > [service files](../assets/pkg/aur#services) **are** included and enabled
# Installing from Source
Firstly, you'll need to build the package, this also includes man pages, default config, themes and other files you might need.
To build it you only need to have some basic packages (should come pre-installed in almost all distros): `make`, `gcc` or another `gcc`ish compiler, and libpam headers. If it builds, it surely works anyways.
```sh
git clone https://github.com/javalsai/lidm.git
cd lidm
make # 👍
```
> [!NOTE]
> There are pre-built binaries on the [releases tab](https://github.com/javalsai/lidm/releases) too.
Then you can install the files onto your filesystem with:
```sh
make install
```
This will install mostly into `/usr/local` by default, this path is mostly unused nowadays (systemd can load services from it but man usually doesn't find manual pages in there) and could feel like lidm didn't install at all. You can add `PREFIX=/usr` to install along the rest of your system packages if you wish.
And additionally, to install service files (start-up behavior). <sup>[more docs](../assets/services/README.md)</sup>
```sh
# automatically detects your init system
# and install service file (for tty7)
make install-service
# or if you don't like autodetection
make install-service-systemd # systemd
make install-service-dinit # dinit
make install-service-runit # runit (/etc/sv)
make install-service-runit-etc # runit (/etc/runit/sv)
make install-service-openrc # openrc
make install-service-s6 # s6 (/etc/sv)
make install-service-s6-etc # s6 (/etc/s6/sv)
# For runit and s6, some distros (e.g. Artix) like to put it in /etc/<init>/sv
# to better isolate their packages while other distros (e.g. Void) just put it
# in /etc/sv
```

View File

@@ -22,10 +22,12 @@ make \
The list of possible `#define`s is: The list of possible `#define`s is:
| Name | Default | Description | Env Override? | | Name | Default | Description | Env Override? |
| ---------------------- | ------------------------------- | -------------------------------------------------------------------------- | ------------------------ | | -------------------------- | ------------------------------------- | -------------------------------------------------------------------------- | ------------------------ |
| `PAM_SERVICE_FALLBACK` | `"login"` | Name of the default PAM module to use. Defaults to the distro's `"login"`. | Yes (`LIDM_PAM_SERVICE`) | | `PAM_SERVICE_FALLBACK` | `"login"` | Name of the default PAM module to use. Defaults to the distro's `"login"`. | Yes (`LIDM_PAM_SERVICE`) |
| `SESSIONS_XSESSIONS` | `"/usr/share/xsessions"` | | No | | `SESSIONS_XSESSIONS` | `"/usr/share/xsessions"` | | No |
| `SESSIONS_XSESSIONS_LOCAL` | `"/usr/local/share/xsessions"` | | No |
| `SESSIONS_WAYLAND` | `"/usr/share/wayland-sessions"` | | No | | `SESSIONS_WAYLAND` | `"/usr/share/wayland-sessions"` | | No |
| `SESSIONS_WAYLAND_LOCAL` | `"/usr/local/share/wayland-sessions"` | | No |
| `LIDM_CONF_PATH` | `"/etc/lidm.ini"` | Path of the default configuration. | Yes (`LIDM_CONF`) | | `LIDM_CONF_PATH` | `"/etc/lidm.ini"` | Path of the default configuration. | Yes (`LIDM_CONF`) |
# Other Build Settings # Other Build Settings
@@ -51,7 +53,9 @@ But this can be changed by just passing those env variables, for example, in the
## Target Directory ## Target Directory
`DESTDIR` can be used to for installation recipes to install on alternative root directories. Along with `PREFIX` (defaults to `/usr`) for systems which don't use the common `/usr` structure. e.g. `make install DESTDIR=$out PREFIX=` `DESTDIR` can be used to for installation recipes to install on alternative root directories. Along with `PREFIX` (defaults to `/usr/local`, packaging this you'll probably want to make it `/usr`) for systems which don't use the common `/usr` structure. e.g. `make install DESTDIR=$out PREFIX=`
`/etc` is sometimes in that `PREFIX` and sometimes not, be careful.
```txt ```txt
$ fd -t f . --base-directory $out $ fd -t f . --base-directory $out
@@ -67,7 +71,7 @@ To ease most of the installation process there's several `make` recipes to insta
- `make` / `make lidm`: Builds the app binary. - `make` / `make lidm`: Builds the app binary.
- `make install`: Attempts to install the binary, place a default config file in `/etc/lidm.ini` and install the man pages. - `make install`: Attempts to install the binary, place a default config file in `/etc/lidm.ini` and install the man pages.
- `make install-service-(systemd|dinit|runit|openrc|s6)(|-etc)`: Just check the source, service files for different init systems and `-etc` variants for alternative paths. - `make install-service-(systemd|dinit|runit|openrc|s6)(|-etc)`: Just check the source, service files for different init systems and `-etc` variants for alternative paths. You might need `FORCE=1` in the environment if you are packaging for other init system or scripting.
- `make print-version`: Outputs the current version in the `Makefile` for scripts that might want to extract that info. - `make print-version`: Outputs the current version in the `Makefile` for scripts that might want to extract that info.
You can choose to use these packages or create your own service files / etc. There's are merely suggestions on what to use. You can choose to use these packages or create your own service files / etc. There's are merely suggestions on what to use.

View File

@@ -6,6 +6,7 @@
#include "macros.h" #include "macros.h"
char* NULLABLE search_path(const char* NNULLABLE for_binary);
int execvpe_desktop(char** args, char* NNULLABLE* NNULLABLE envlist); int execvpe_desktop(char** args, char* NNULLABLE* NNULLABLE envlist);
int parse_exec_string(const char* exec_s, int* arg_count, char*** args); int parse_exec_string(const char* exec_s, int* arg_count, char*** args);
void free_parsed_args(int arg_count, char** args); void free_parsed_args(int arg_count, char** args);

8
include/signal_handler.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef SIGNALHANDLERH_
#define SIGNALHANDLERH_
// handle SIGTERM by sending SIGTERM to all children, resulting
// in a graceful graphical shutdown
void setup_sigterm();
#endif /* SIGNALHANDLERH_ */

90
services.mk Normal file
View File

@@ -0,0 +1,90 @@
install-service:
@if command -v systemctl &> /dev/null; then \
make install-service-systemd; \
elif command -v dinitctl &> /dev/null; then \
make install-service-dinit; \
elif command -v sv &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-runit; \
elif [ -d /etc/runit/sv ]; then \
make install-service-runit-etc; \
else \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
elif command -v rc-update &> /dev/null; then \
make install-service-openrc; \
elif command -v s6-service &> /dev/null; then \
if [ -d /etc/sv ]; then \
make install-service-s6; \
elif [ -d /etc/r6nit/sv ]; then \
make install-service-s6-etc; \
else \
printf '\033[31m%s\033[0m\n' "Unknown init system structure, skipping service install..." >&2; \
fi \
else \
printf '\033[1;31m%s\033[0m\n' "Unknown init system, skipping service install..." >&2; \
fi
install-service-systemd:
install -Dm644 ./assets/services/systemd.service ${DESTDIR}${PREFIX}/lib/systemd/system/lidm.service
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'systemctl enable lidm'"
install-service-dinit:
install -m644 ./assets/services/dinit ${DESTDIR}/etc/dinit.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'dinitctl enable lidm'"
install-service-runit:
@if [ ! -e /etc/sv ] && [ -d /etc/runit/sv ] && [ -z "$$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/runit/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/sv/lidm /var/service' or your distro equivalent"
install-service-runit-etc:
@if [ ! -e /etc/runit/sv ] && [ -d /etc/sv ] && [ -z "$$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/runit/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-runit'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/runit/sv/lidm
cp -r --update=all ./assets/services/runit/* ${DESTDIR}/etc/runit/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'ln -s ${DESTDIR}/etc/runit/sv/lidm /run/runit/service' or your distro equivalent"
install-service-openrc:
install -m755 ./assets/services/openrc ${DESTDIR}/etc/init.d/lidm
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 'rc-update add lidm'"
install-service-s6:
@if [ ! -e /etc/sv ] && [ -d /etc/s6/sv ] && [ -z "$$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/sv doesn't exist but /etc/s6/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6-etc'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
install-service-s6-etc:
@if [ ! -e /etc/s6/sv ] && [ -d /etc/sv ] && [ -z "$$FORCE" ]; then \
printf '\033[31m%s\033[0m\n' "/etc/s6/sv doesn't exist but /etc/sv does" >&2; \
printf '\033[31m%s\033[0m\n' "you probably meant to 'make install-service-s6'" >&2; \
exit 1; \
fi
mkdir -p ${DESTDIR}/etc/s6/sv/lidm
cp -r --update=all ./assets/services/s6/* ${DESTDIR}/etc/s6/sv/lidm/
@printf '\033[1m%s\033[0m\n\n' " don't forget to run 's6-service add default lidm' and 's6-db-reload'"
uninstall-service:
rm -rf \
${DESTDIR}${PREFIX}/lib/systemd/system/lidm.service \
${DESTDIR}/etc/dinit.d/lidm \
${DESTDIR}/etc/sv/lidm \
${DESTDIR}/etc/runit/sv/lidm \
${DESTDIR}/etc/init.d/lidm \
${DESTDIR}/etc/s6/sv/lidm
.PHONY: install-service uninstall-service \
install-service-s6 \
install-service-s6-etc \
install-service-dinit \
install-service-runit \
install-service-runit-etc \
install-service-openrc \
install-service-systemd

View File

@@ -23,9 +23,7 @@
#include "ui.h" #include "ui.h"
#include "util.h" #include "util.h"
#define DEFAULT_XORG_DISPLAY 0 #define XORG_MESSAGE_LENGTH 16
// no PATH search for now
#define XORG_COMMAND "/usr/bin/X"
static void try_source_file(struct Vector* NNULLABLE vec_envlist, static void try_source_file(struct Vector* NNULLABLE vec_envlist,
char* NNULLABLE filepath) { char* NNULLABLE filepath) {
@@ -98,64 +96,121 @@ struct child_msg {
bool err; bool err;
}; };
// TODO: OR check if xorg_pid fail exited /// block until X returns the display number or an error occurs
static int wait_for_x_ready(const int xorg_pipefd[1], __pid_t xorg_pid) { static bool x_get_display(const int xorg_pipefd[2], int* display) {
// TODO char buffer[XORG_MESSAGE_LENGTH];
UNUSED(xorg_pipefd); bool status;
UNUSED(xorg_pid);
sleep(2); close(xorg_pipefd[1]);
return 0; ssize_t bytes_read = read(xorg_pipefd[0], buffer, sizeof(buffer) - 1);
buffer[bytes_read] = '\0';
if (bytes_read > 0) {
char* endptr;
int val = (int)strtol(buffer, &endptr, 10);
if (endptr == buffer) {
(void)fputs("failed to parse Xorg display response\n", stderr);
status = false;
} else {
*display = val;
status = true;
}
} else if (bytes_read == 0) {
(void)fputs("Xorg pipe closed\n", stderr);
status = false;
} else {
perror("read");
status = false;
}
close(xorg_pipefd[0]);
return status;
}
/// small helper to push dyn arr
static void push_dyn_arr(void*** arr, void* item) {
struct Vector vec = vec_from_raw(*arr);
vec_push(&vec, item);
*arr = vec_as_raw(vec);
} }
// TODO: properly pass this down // TODO: properly pass this down
extern int vt; extern int vt;
// TODO: add error msgs
static void launch_with_xorg_server(struct session_exec* NNULLABLE exec, static void start_xorg_server(struct passwd* pw, char** NNULLABLE envlist,
struct passwd* pw, int xorg_pipefd[2]) {
char** NNULLABLE envlist) { close(xorg_pipefd[0]);
int xorg_pipefd[2];
pipe(xorg_pipefd);
(void)fflush(NULL);
__pid_t xorg_pid = fork();
if (xorg_pid == 0) {
if (!pw->pw_dir) _exit(EXIT_FAILURE); if (!pw->pw_dir) _exit(EXIT_FAILURE);
// !!!!!!!!!! ATTENTION: this fails silently, of course add failure msgs but // !!!!!!!!!! ATTENTION: this fails silently, of course add failure msgs but
// for now I can't so be careful // for now I can't so be careful
if (vt == -1) _exit(EXIT_FAILURE); if (vt == -1) _exit(EXIT_FAILURE);
char* display_thing; // pass the pipe so Xorg can write the DISPLAY value in there
asprintf(&display_thing, ":%d", DEFAULT_XORG_DISPLAY); char* fd_str;
if (!display_thing) _exit(EXIT_FAILURE); asprintf(&fd_str, "%d", xorg_pipefd[1]);
if (!fd_str) _exit(EXIT_FAILURE);
char* vt_path; char* vt_path;
asprintf(&vt_path, "vt%d", vt); asprintf(&vt_path, "vt%d", vt);
if (!vt_path) { if (!vt_path) {
free(display_thing); free(fd_str);
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
// dup2(xorg_pipefd[1], STDERR_FILENO); char* xorg_path = search_path("Xorg");
// dup2(xorg_pipefd[1], STDOUT_FILENO); if (!xorg_path) {
// close(xorg_pipefd[0]); (void)fputs("couldn't find Xorg binary in PATH, sure it's installed?\n",
// close(xorg_pipefd[1]); stderr);
_exit(EXIT_FAILURE);
int exit = execle(XORG_COMMAND, XORG_COMMAND, display_thing, vt_path, NULL,
envlist);
perror("exec");
// execle("X", "X", display_thing, vt_path, "-auth", xauth_path,
// "-nolisten", "tcp", "-background", "none", NULL, envlist);
printf("wtf3\n");
(void)fflush(stdout);
free(vt_path);
free(display_thing);
_exit(exit);
} }
wait_for_x_ready(xorg_pipefd, xorg_pid); int exit = execle(xorg_path, xorg_path, "-displayfd", fd_str, vt_path, NULL,
envlist);
perror("exec");
__pid_t xorg_session_pid = fork(); free(vt_path);
free(fd_str);
free(xorg_path);
_exit(exit);
}
// TODO: add error msgs
/// returns on completion
static void launch_with_xorg_server(struct session_exec* NNULLABLE exec,
struct passwd* pw,
char** NNULLABLE envlist) {
int xorg_pipefd[2];
if (pipe(xorg_pipefd) == -1) _exit(EXIT_FAILURE);
(void)fflush(NULL);
pid_t xorg_pid = fork();
if (xorg_pid == 0) {
start_xorg_server(pw, envlist, xorg_pipefd);
}
int display = 0;
if (!x_get_display(xorg_pipefd, &display)) {
(void)fputs("failed to get X display, aborting\n", stderr);
int status;
waitpid(xorg_pid, &status, 0);
_exit(EXIT_FAILURE);
}
char* display_env;
asprintf(&display_env, "DISPLAY=:%d", display);
if (!display_env) {
(void)fputs("failure allocating memory for DISPLAY string\n", stderr);
_exit(EXIT_FAILURE);
}
// convert back for convenient push-ing
push_dyn_arr((void***)&envlist, display_env);
if (!envlist) {
(void)fputs("failure allocating memory for DISPLAY env\n", stderr);
_exit(EXIT_FAILURE);
}
(void)fflush(NULL);
pid_t xorg_session_pid = fork();
if (xorg_session_pid == 0) { if (xorg_session_pid == 0) {
int exit = session_exec_exec(exec, envlist); int exit = session_exec_exec(exec, envlist);
perror("exec error"); perror("exec error");
@@ -165,20 +220,16 @@ static void launch_with_xorg_server(struct session_exec* NNULLABLE exec,
// looks weird, waiting on -1 should wait on any child and then just check if // looks weird, waiting on -1 should wait on any child and then just check if
// its xorg server or the session and kill the other waiting on it // its xorg server or the session and kill the other waiting on it
__pid_t pid; pid_t pid;
int status; // not even read for now int status; // not even read for now
while ((pid = waitpid(-1, &status, 0)) > 0) { while ((pid = waitpid(-1, &status, 0)) > 0) {
if (pid == xorg_pid || pid == xorg_session_pid) { if (pid == xorg_pid || pid == xorg_session_pid) {
__pid_t pid_to_kill = pid ^ xorg_pid ^ xorg_session_pid; pid_t pid_to_kill = pid ^ xorg_pid ^ xorg_session_pid;
if (pid == xorg_pid) printf("Xorg server died\n"); if (pid == xorg_pid) printf("Xorg server died\n");
if (pid == xorg_session_pid) printf("Xorg session died\n"); if (pid == xorg_session_pid) printf("Xorg session died\n");
kill(pid_to_kill, SIGTERM); kill(pid_to_kill, SIGTERM);
waitpid(pid_to_kill, &status, 0); waitpid(pid_to_kill, &status, 0);
printf("wtf %d, x%d s%d - k%d\n", status, xorg_pid, xorg_session_pid,
pid_to_kill);
(void)fflush(stdout);
sleep(10);
break; break;
} }
@@ -218,6 +269,7 @@ inline static void forked(int pipefd[2], struct passwd* pw,
if (session->type == XORG) { if (session->type == XORG) {
launch_with_xorg_server(&session->exec, pw, envlist); launch_with_xorg_server(&session->exec, pw, envlist);
_exit(EXIT_SUCCESS);
} else { } else {
int exit = session_exec_exec(&session->exec, envlist); int exit = session_exec_exec(&session->exec, envlist);
perror("exec error"); perror("exec error");
@@ -260,16 +312,6 @@ bool launch(char* user, char* passwd, struct session session, void (*cb)(void),
struct Vector envlist_vec = vec_from_raw((void**)env_ret.envlist); struct Vector envlist_vec = vec_from_raw((void**)env_ret.envlist);
if (session.type == XORG) {
char* display_env;
asprintf(&display_env, "DISPLAY=:%d", DEFAULT_XORG_DISPLAY);
if (!display_env) {
print_err("alloc error");
return false;
}
vec_push(&envlist_vec, display_env);
}
source_paths(&envlist_vec, &config->behavior.source, pw->pw_dir, source_paths(&envlist_vec, &config->behavior.source, pw->pw_dir,
&config->behavior.user_source); &config->behavior.user_source);
char** envlist = (char**)vec_as_raw(envlist_vec); char** envlist = (char**)vec_as_raw(envlist_vec);

View File

@@ -17,7 +17,7 @@
// returns NULL on any error // returns NULL on any error
// otherwise it returns the absolute path of the program that MUST BE FREED // otherwise it returns the absolute path of the program that MUST BE FREED
static char* NULLABLE search_path(const char* NNULLABLE for_binary) { char* NULLABLE search_path(const char* NNULLABLE for_binary) {
if (strchr(for_binary, '/') != NULL) { if (strchr(for_binary, '/') != NULL) {
// skip absolute paths // skip absolute paths
return strdup(for_binary); return strdup(for_binary);

View File

@@ -21,19 +21,17 @@ int read_launch_state(struct LaunchState* NNULLABLE state) {
}; };
size_t num = 0; size_t num = 0;
if (getline(&state->username, &num, state_fd) < 0) goto fail; ssize_t chars = getline(&state->username, &num, state_fd);
// not sure I can actually prove it but ughh, getline < 0 will ensure there's if (chars < 0) goto fail;
// something in the string and then I think strcspn is bounded to the final if (state->username[chars] == '\n') state->username[chars] = 0;
// null byte, so it shouldn't go over
// NOLINTNEXTLINE(clang-analyzer-security.ArrayBound)
state->username[strcspn(state->username, "\n")] = 0;
num = 0; num = 0;
if (getline(&state->session_opt, &num, state_fd) < 0) { chars = getline(&state->session_opt, &num, state_fd);
if (chars < 0) {
free(state->session_opt); free(state->session_opt);
goto fail; goto fail;
} }
state->session_opt[strcspn(state->session_opt, "\n")] = 0; if (state->session_opt[chars] == '\n') state->session_opt[chars] = 0;
(void)fclose(state_fd); (void)fclose(state_fd);
return 0; return 0;

View File

@@ -12,12 +12,13 @@
#include "log.h" #include "log.h"
#include "macros.h" #include "macros.h"
#include "sessions.h" #include "sessions.h"
#include "signal_handler.h"
#include "ui.h" #include "ui.h"
#include "users.h" #include "users.h"
#include "util.h" #include "util.h"
#include "version.h"
#define DATESTR_MAXBUFSIZE 0x20 #define DATESTR_MAXBUFSIZE 0x20
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
// Logger // Logger
char* log_output = getenv("LIDM_LOG"); char* log_output = getenv("LIDM_LOG");
@@ -85,6 +86,8 @@ int main(int argc, char* argv[]) {
struct Vector users = get_human_users(); struct Vector users = get_human_users();
struct Vector sessions = get_avaliable_sessions(); struct Vector sessions = get_avaliable_sessions();
setup_sigterm();
int ret = load(&users, &sessions); int ret = load(&users, &sessions);
if (ret == 0) execl(argv[0], argv[0], NULL); if (ret == 0) execl(argv[0], argv[0], NULL);
} }

View File

@@ -22,13 +22,19 @@ struct source_dir {
#ifndef SESSIONS_XSESSIONS #ifndef SESSIONS_XSESSIONS
#define SESSIONS_XSESSIONS "/usr/share/xsessions" #define SESSIONS_XSESSIONS "/usr/share/xsessions"
#endif #endif
#ifndef SESSIONS_XSESSIONS_LOCAL
#define SESSIONS_XSESSIONS_LOCAL "/usr/local/share/xsessions"
#endif
#ifndef SESSIONS_WAYLAND #ifndef SESSIONS_WAYLAND
#define SESSIONS_WAYLAND "/usr/share/wayland-sessions" #define SESSIONS_WAYLAND "/usr/share/wayland-sessions"
#endif #endif
static const struct source_dir SOURCES[] = { #ifndef SESSIONS_WAYLAND_LOCAL
{XORG, SESSIONS_XSESSIONS}, #define SESSIONS_WAYLAND_LOCAL "/usr/local/share/wayland-sessions"
#endif
static const struct source_dir SOURCES[] = {{XORG, SESSIONS_XSESSIONS},
{XORG, SESSIONS_XSESSIONS_LOCAL},
{WAYLAND, SESSIONS_WAYLAND}, {WAYLAND, SESSIONS_WAYLAND},
}; {WAYLAND, SESSIONS_WAYLAND_LOCAL}};
static struct Vector* cb_sessions = NULL; static struct Vector* cb_sessions = NULL;

29
src/signal_handler.c Normal file
View File

@@ -0,0 +1,29 @@
#include <errno.h>
#include <stddef.h>
#include <sys/wait.h>
#include <unistd.h>
#include "signal_handler.h"
static void handle_sigterm(int sig) {
(void)sig;
(void)signal(SIGTERM, SIG_IGN);
kill(-getpgrp(), SIGTERM);
int status;
while (waitpid(-1, &status, 0) > 0 || errno == EINTR) {
}
_exit(0);
}
void setup_sigterm() {
setpgid(0, 0);
struct sigaction sa;
sa.sa_handler = handle_sigterm;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, NULL);
}

View File

@@ -67,6 +67,11 @@ static void process_sigwinch(int signal) {
need_resize = 1; need_resize = 1;
} }
static inline void draw_bg() {
// apply bg color to all screen
printf("\x1b[%sm\x1b[2J", g_config->colors.bg);
}
void setup(struct config* config) { void setup(struct config* config) {
g_config = config; g_config = config;
@@ -76,10 +81,9 @@ void setup(struct config* config) {
term.c_lflag &= ~(ICANON | ECHO); term.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDOUT_FILENO, TCSANOW, &term); tcsetattr(STDOUT_FILENO, TCSANOW, &term);
// save cursor pos, save screen, set color and reset screen // save cursor pos, save screen
// (applying color to all screen) printf("\x1b[s\x1b[?47h");
printf("\x1b[s\x1b[?47h\x1b[%s;%sm\x1b[2J", g_config->colors.bg, draw_bg();
g_config->colors.fg);
(void)atexit(restore_all); (void)atexit(restore_all);
(void)signal(SIGINT, signal_handler); (void)signal(SIGINT, signal_handler);
@@ -186,6 +190,7 @@ void ui_update_ofield(struct opts_field* NNULLABLE self) {
ui_update_field(input); ui_update_field(input);
} }
/// draw everything
void scratch_print_ui() { void scratch_print_ui() {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window); ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
box_start = (struct uint_point){ box_start = (struct uint_point){
@@ -201,7 +206,8 @@ void scratch_print_ui() {
return; return;
} }
printf("\033[2J\033[H"); // Clear screen printf("\033[2J\033[H\033c"); // Clear screen
draw_bg();
/// PRINTING /// PRINTING
// printf box // printf box
@@ -313,6 +319,8 @@ int load(struct Vector* users, struct Vector* sessions) {
&restore_all, g_config)) { &restore_all, g_config)) {
print_passwd(utf8len(of_passwd.efield.content), true); print_passwd(utf8len(of_passwd.efield.content), true);
ui_update_cursor_focus(); ui_update_cursor_focus();
} else {
scratch_print_ui();
} }
} else if (ansi_key == A_UP || ansi_key == A_DOWN) { } else if (ansi_key == A_UP || ansi_key == A_DOWN) {
st_ch_focus(ansi_key == A_DOWN ? 1 : -1); st_ch_focus(ansi_key == A_DOWN ? 1 : -1);
@@ -336,6 +344,8 @@ int load(struct Vector* users, struct Vector* sessions) {
&restore_all, g_config)) { &restore_all, g_config)) {
print_passwd(utf8len(of_passwd.efield.content), true); print_passwd(utf8len(of_passwd.efield.content), true);
ui_update_cursor_focus(); ui_update_cursor_focus();
} else {
scratch_print_ui();
} }
} else } else
st_kbd_type(seq, g_config->behavior.include_defshell); st_kbd_type(seq, g_config->behavior.include_defshell);