Merge pull request #11 from grialion/master

feat(chvt): use custom implementation instead of system()
This commit is contained in:
javalsai 2024-08-07 00:10:13 +02:00 committed by GitHub
commit a393cda7e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 9 deletions

View File

@ -10,10 +10,10 @@ ALLFLAGS=$(CFLAGS) -I$(IDIR)
LIBS=-lm -lpam -lpam_misc LIBS=-lm -lpam -lpam_misc
_DEPS = util.h ui.h config.h auth.h efield.h keys.h users.h sessions.h _DEPS = util.h ui.h config.h auth.h efield.h keys.h users.h sessions.h chvt.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o util.o ui.o config.o auth.o efield.o users.o sessions.o _OBJ = main.o util.o ui.o config.o auth.o efield.o users.o sessions.o chvt.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS) $(ODIR)/%.o: $(CDIR)/%.c $(DEPS)

18
include/chvt.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef _CHVTH_
#define _CHVTH_
#include <fcntl.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <sys/ioctl.h>
#include <unistd.h>
/**
* @brief change foreground virtual terminal to `n`
*
* @param n virtual terminal number
* @return int non-negative value on success
*/
int chvt(int n);
#endif

25
src/chvt.c Normal file
View File

@ -0,0 +1,25 @@
#include <stdio.h>
#include <chvt.h>
static char *vterms[] = {"/dev/tty", "/dev/tty0", "/dev/vc/0", "/dev/systty",
"/dev/console"};
int chvt(int n) {
fprintf(stderr, "activating vt %d\n", n);
char c = 0;
for (int i = 0; i < sizeof(vterms) / sizeof(vterms[0]); i++) {
int fd = open(vterms[i], O_RDWR);
if (fd >= 0 && isatty(fd) && ioctl(fd, KDGKBTYPE, &c) == 0 && c < 3) {
if (ioctl(fd, VT_ACTIVATE, n) < 0 || ioctl(fd, VT_WAITACTIVE, n) < 0) {
fprintf(stderr, "Couldn't activate vt %d\n", n);
return -1;
}
return 0;
}
close(fd);
}
fprintf(stderr, "Couldn't get a file descriptor referring to the console.\n");
return -1;
}

View File

@ -1,25 +1,34 @@
#include <errno.h>
#include <limits.h>
#include <pwd.h> #include <pwd.h>
#include <stdbool.h> #include <stdbool.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <chvt.h>
#include <config.h> #include <config.h>
#include <sessions.h> #include <sessions.h>
#include <ui.h> #include <ui.h>
#include <users.h> #include <users.h>
void chvt(char *arg) { int chvt_str(char *str) {
size_t bsize = snprintf(NULL, 0, "chvt %s", arg) + 1; char *err;
char *buf = malloc(bsize); long i = strtol(str, &err, 10);
snprintf(buf, bsize, "chvt %s", arg); if (errno) {
system(buf); perror("strol");
free(buf); return -1;
}
// I'm not gonna elaborate on this....
if (i > INT_MAX || i < INT_MIN || *err)
return -1;
return chvt((int)i);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc == 2) if (argc == 2)
chvt(argv[1]); chvt_str(argv[1]);
struct config *config = parse_config("/etc/lidm.ini"); struct config *config = parse_config("/etc/lidm.ini");
if (config == NULL) { if (config == NULL) {