From 7e22bd716fe6bc27542182828c1aee41d6e42d0b Mon Sep 17 00:00:00 2001 From: Igor Kolokolnikov Date: Tue, 15 Sep 2026 20:37:35 -0700 Subject: [PATCH] Initial commit. --- Makefile | 92 +++++++++++++++++++++++++++++++++++++++++ caffeine.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 Makefile create mode 100644 caffeine.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..374072b --- /dev/null +++ b/Makefile @@ -0,0 +1,92 @@ +UNAME_M := $(shell uname -m) + +ifeq ($(UNAME_M),x86_64) + ARCH := ARCHITECTURE_X64 +else ifneq ($(filter $(UNAME_M),i686,i386),) + ARCH := ARCHITECTURE_X86 +else ifneq ($(filter $(UNAME_M),aarch64 arm64),) + ARCH := ARCHITECTURE_ARM64 +else ifneq ($(filter $(UNAME_M),armv7l armv6l),) + ARCH := ARCHITECTURE_ARM32 +endif + +UNAME_E := $(shell [ $$(printf '\01\00' | od -An -tu2) -eq 1 ] && \ + echo "little" || echo "big") + +ifeq ($(UNAME_E),little) + ENDIANESS := LITTLE_ENDIAN +else ifeq ($(UNAME_E),little) + ENDIANESS := BIG_ENDIAN +endif + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) + OS := OS_MACOS +else ifeq ($(UNAME_S),Linux) + OS := OS_LINUX +endif + +CC = gcc + +ifeq ($(CC),clang) + COMP := COMPILER_CLANG +else ifeq ($(CC),gcc) + COMP := COMPILER_GCC +endif + +# -ansi -pedantic -pedantic-errors +CFLAGS = -Wno-long-long -Wall -Wextra \ + -Wincompatible-pointer-types \ + -Wint-conversion -Wformat \ + -Wno-strict-prototypes -Wno-missing-field-initializers \ + -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable \ + -Wno-unused-but-set-variable \ + -fno-show-column + +ifeq ($(COMP),COMPILER_CLANG) + CFLAGS += -fno-caret-diagnostics +else ifeq ($(COMP),COMPILER_GCC) + CFLAGS += -fno-diagnostics-show-caret +endif + +ifeq ($(OS),OS_MACOS) + FLAGS = -glldb + INCLUDE = + LIBS = + FRAMEWORKS = +else ifeq ($(OS),OS_LINUX) + FLAGS = -O3 # -ggdb -DDEBUG=1 -DINTERNAL=1 + INCLUDE = + LIBS = + FRAMEWORKS = -lX11 -lXss +endif + +EXE = caffeine + +default: $(EXE) + +$(EXE): $(EXE).c + $(CC) $(CFLAGS) $(FLAGS) \ + -D$(ARCH)=1 -D$(ENDIANESS)=1 -D$(OS)=1 -D$(COMP)=1 \ + -D_DEFAULT_SOURCE -DHAVE_SHADOW_H \ + $(INCLUDE) $^ $(LIBS) \ + $(FRAMEWORKS) -o $@ $(ifneq $(filter $(OS), OS_MACOS OS_LINUX), \ + /link /FORCE:MULTIPLE) + +watch: + @ while true; do \ + inotifywait -q -q -e 'modify' . && clear && make -B; \ + done + +perf: + perf record --call-graph dwarf ./$(EXE) + +run: + @ clear; ./$(EXE) + +install: + mv ./$(EXE) /usr/local/bin + +clean: + @ rm -rf $(EXE) $(EXE).dSYM diff --git a/caffeine.c b/caffeine.c new file mode 100644 index 0000000..145555c --- /dev/null +++ b/caffeine.c @@ -0,0 +1,119 @@ +#include /* access */ +#include /* exit */ +#include +#include +#include +#include + +#include + +#define TEMP_FILE "/tmp/caffeine" + +char file_exists(const char *filename) +{ + return access(filename, F_OK) != -1; +} + +void daemonize() +{ + close(0); + close(1); + close(2); + open("/dev/null", O_RDONLY); /* stdin */ + open("/dev/null", O_WRONLY); /* stdout */ + open("/dev/null", O_WRONLY); /* stderr */ + chdir("/"); + int pid = fork(); + if(pid > 0) + exit(0); + setsid(); + pid = fork(); + if(pid > 0) + exit(0); +} + +#if 1 +static volatile sig_atomic_t n = 0; + +void usr1hdl(int sig) +{ + int save_errno = errno; + signal(SIGUSR1, usr1hdl); + n = 1; + errno = save_errno; +} + +void termhdl(int sig) +{ + int save_errno = errno; + signal(SIGTERM, termhdl); + n = 2; + errno = save_errno; +} +#endif + +int main(int argc, char *argv[]) +{ + Display *dpy; + int event_base, error_base, major, minor; + int is_on; + + /*daemonize();*/ + + signal(SIGUSR1, usr1hdl); + signal(SIGTERM, termhdl); + + openlog("caffeine", 0, LOG_USER); + syslog(LOG_INFO, "Daemon started, pid == %d", getpid()); + + dpy = XOpenDisplay(0); + if(!dpy) { + syslog(LOG_ERR, "Failed to open display."); + return 1; + } + + if(!XScreenSaverQueryExtension(dpy, &event_base, &error_base)) { + syslog(LOG_ERR, "XScreenSaver extension does not exist."); + return 2; + } + + XScreenSaverQueryVersion(dpy, &major, &minor); + if(!(major > 1 || (major == 1 && minor >= 1))) { + syslog(LOG_ERR, "XScreenSaver extension is too old, need >=1.1."); + return 3; + } + + is_on = 0; + for(;;) { + pause(); + if(n == 0) { + /* do nothing */ + } else if(n == 1) { + is_on = !is_on; + if(is_on) { + syslog(LOG_INFO, "Enabling..."); + creat(TEMP_FILE, 0644); + XScreenSaverSuspend(dpy, True); + } else { + syslog(LOG_INFO, "Disabling..."); + unlink(TEMP_FILE); + XScreenSaverSuspend(dpy, False); + } + XSync(dpy, False); + } else if(n == 2) { + syslog(LOG_INFO, "Shutting down..."); + unlink(TEMP_FILE); + XScreenSaverSuspend(dpy, False); + XSync(dpy, False); + break; + } else { + /* unknown state */ + } + + n = 0; + } + + closelog(); + + return 0; +}