#include #include #include #include #include #include #include #include #include #include /* configuration */ #define ARGV "xterm", "xterm", "-e", "/usr/local/bin/ksh", "-w", writefile, NULL #define MAX_CMD 1000 #define MAX_LOOK 1000 /* state */ Atom pidatom; Display *display; #define die(...) do{fprintf(stderr,__VA_ARGS__);exit(1);}while(0) unsigned char *pidprop = 0; Window findwindow(unsigned int pid, Window w) { Atom type; int format; unsigned int i, nchildren; unsigned long nitems, bytes_after; Window *children, _root, parent; pidprop = 0; if (XGetWindowProperty(display, w, pidatom, 0, 1, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &pidprop) == Success && pidprop && pid == *((unsigned long *)pidprop)) return w; if (XQueryTree(display, w, &_root, &parent, &children, &nchildren)) for (i = 0; i < nchildren; i++) { w = findwindow(pid, children[i]); if (w) return w; } return 0; } char * wd(char *path) { char *username, *r; username = getenv("USER"); r = strdup(path); if (strncmp(r, "/home/", 6) == 0) { r += 5; if (strncmp(r + 1, username, strlen(username)) == 0) r += strlen(username); r[0] = '~'; } return r; } int main(int argc, char *argv[]) { char *cwd, *cmd, *line, *writefile; FILE *writefp; int i; pid_t child; size_t size; ssize_t len; Window root, w; /* create fifo */ writefile = malloc(40*sizeof(char)); if (writefile == NULL) err(1, "malloc"); sprintf(writefile, "/var/tmp/tterm/%d.w", getpid()); if (mkdir("/var/tmp/tterm", 0700) == -1 && errno != EEXIST) err(1, "mkdir"); unlink(writefile); if (mkfifo(writefile, 0600) == -1) err(1, "mkfifo"); /* start terminal */ if ((child = fork()) == 0) { execlp(ARGV); err(1, "execvp"); } /* find new window */ display = XOpenDisplay(0); if (display == NULL) die("could not open display\n"); root = XDefaultRootWindow(display); pidatom = XInternAtom(display, "_NET_WM_PID", 1); if (pidatom == None) die("no _NET_WM_PID atom found\n"); for (i = 0; !w && i++ < MAX_LOOK; w = findwindow(child, root)) ; if (!w) die("could not find window\n"); /* watch fifo and update title */ writefp = fopen(writefile, "r"); if (writefp == NULL) err(1, "fopen"); cmd = malloc(MAX_CMD*sizeof(char)); if (cmd == NULL) err(1, "malloc"); line = NULL; size = 0; while ((len = getline(&line, &size, writefp)) != -1) { if (strncmp(line, "cwd", 3) == 0) { line += 3; line[len-4] = 0; /* chomp */ cwd = wd(line); XStoreName(display, w, cwd); XFlush(display); } else if (strncmp(line, "cmd", 3) == 0) { line += 3; line[len-4] = 0; /* chomp */ snprintf(cmd, MAX_CMD, "%s (%s)", line, cwd); XStoreName(display, w, cmd); XFlush(display); } else { XStoreName(display, w, cwd); XFlush(display); } } unlink(writefile); XCloseDisplay(display); }