/* XI.C * Copyright (c) 2017, 2018 Jesse McClure * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include static volatile int xrunning = 0; void handler(int sig) { if (sig == SIGUSR1) xrunning = 1; if (sig == SIGCHLD || sig == SIGTERM) xrunning = 0; } int server(const char *dpy, const char *tty, const char *xauth) { const char *xorg = "/usr/lib/Xorg"; int pid; if ((pid=fork()) < 0) exit(1); else if (pid > 0) return pid; signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGUSR1, SIG_IGN); execl(xorg, xorg, dpy, tty, "-keeptty", "-nolisten", "tcp", "-quiet", "-auth", xauth, NULL); _exit(2); } int client(const char *dpy, const char *wm, const char *xauth) { int pid; if ((pid=fork()) < 0) exit(3); else if (pid > 0) return pid; setenv("XAUTHORITY", xauth, 1); setenv("DISPLAY", dpy, 1); execlp(wm, wm, NULL); _exit(4); } int main(int argc, const char **argv) { struct vt_stat vtstat; if (ioctl(0, VT_GETSTATE, &vtstat)) { perror("get_vt"); return 1; } char dpy[] = { ':', '0' + vtstat.v_active, 0 }; char tty[] = { 'v', 't', '0' + vtstat.v_active, 0 }; char xauth[PATH_MAX]; snprintf(xauth, PATH_MAX, "%s/%s", getenv("HOME"), ".Xauthority"); struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGTERM, &sa, NULL); int xpid = server(dpy, tty, xauth); while (!xrunning) pause(); int cpid = client(dpy, (argc > 1 ? argv[1] : "xterm" ), xauth); while (xrunning) pause(); kill(cpid, SIGTERM); waitpid(cpid, NULL, 0); kill(xpid, SIGTERM); waitpid(xpid, NULL, 0); return 0; }