summaryrefslogtreecommitdiffstats
path: root/activevt.c
diff options
context:
space:
mode:
Diffstat (limited to 'activevt.c')
-rw-r--r--activevt.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/activevt.c b/activevt.c
new file mode 100644
index 0000000..01790f9
--- /dev/null
+++ b/activevt.c
@@ -0,0 +1,68 @@
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/vt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+// check if argument is tty[0-9]
+static bool is_vt_basename(const char *s) {
+ return !strncmp(s, "tty", 3) && isdigit(s[3]);
+}
+
+// return the number of the active virtual terminal or -1 on error
+static int get_active_vt() {
+ int dfd = open("/dev", O_RDONLY | O_DIRECTORY);
+ if (dfd < 0) {
+ perror("open /dev");
+ return 1;
+ }
+
+ DIR *d = fdopendir(dfd);
+ if (!d) {
+ perror("fdopendir");
+ close(dfd);
+ return 1;
+ }
+
+ int active_vt = -1;
+ struct dirent *ent;
+
+ while ((ent = readdir(d)) != NULL) {
+ if (!is_vt_basename(ent->d_name))
+ continue;
+
+ int fd = openat(dfd, ent->d_name, O_RDONLY | O_NONBLOCK);
+ if (fd < 0)
+ continue;
+
+ struct vt_stat state;
+ if (ioctl(fd, VT_GETSTATE, &state) == 0) {
+ active_vt = state.v_active;
+ close(fd);
+ break;
+ }
+
+ close(fd);
+ }
+
+ closedir(d);
+
+ return active_vt;
+}
+
+int main(void) {
+ int active_vt = get_active_vt();
+
+ if (active_vt < 0) {
+ fprintf(stderr, "Could not determine active VT\n");
+ return 1;
+ }
+
+ printf("%d\n", active_vt);
+ return 0;
+}