summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tterm.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/tterm.c b/tterm.c
index 648fa5c..3a71821 100644
--- a/tterm.c
+++ b/tterm.c
@@ -20,13 +20,13 @@ Display *display;
#define die(...) do{fprintf(stderr,__VA_ARGS__);exit(1);}while(0)
-unsigned char *pidprop = 0;
-
+/* find window associated with pid */
Window
findwindow(unsigned int pid, Window w)
{
Atom type;
int format;
+ unsigned char *pidprop;
unsigned int i, nchildren;
unsigned long nitems, bytes_after;
Window *children, _root, parent;
@@ -45,18 +45,21 @@ findwindow(unsigned int pid, Window w)
return 0;
}
+/* copy cwd and rewrite /home/ */
char *
-wd(char *path)
+cwdcpy(char *path)
{
- char *username, *r;
+ char *user, *r;
+ int len;
- 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);
+ if (strncmp(path, "/home/", sizeof("/home")-1) == 0) {
+ user = getenv("USER");
+ len = strlen(user);
+ r += sizeof("/home")-1;
+ if (strncmp(r + 1, user, len) == 0)
+ r += len;
r[0] = '~';
}
@@ -72,19 +75,28 @@ main(int argc, char *argv[])
pid_t child;
size_t size;
ssize_t len;
- Window root, w;
-
- /* create fifo */
+ Window w;
- writefile = malloc(40*sizeof(char));
- if (writefile == NULL) err(1, "malloc");
+ if ((display = XOpenDisplay(0)) == NULL)
+ die("could not open display\n");
- sprintf(writefile, "/var/tmp/tterm/%d.w", getpid());
+ /* create fifo directory */
if (mkdir("/var/tmp/tterm", 0700) == -1 && errno != EEXIST)
err(1, "mkdir");
+ /* build fifo path */
+ if ((writefile = malloc(40*sizeof(char))) == NULL)
+ err(1, "malloc");
+ sprintf(writefile, "/var/tmp/tterm/%d.w", getpid());
+
+ /* create fifo */
unlink(writefile);
- if (mkfifo(writefile, 0600) == -1) err(1, "mkfifo");
+ if (mkfifo(writefile, 0600) == -1)
+ err(1, "mkfifo");
+
+ /* retrieve atom for _NET_WM_PID */
+ pidatom = XInternAtom(display, "_NET_WM_PID", 1);
+ if (pidatom == None) die("no _NET_WM_PID atom found\n");
/* start terminal */
if ((child = fork()) == 0) {
@@ -92,35 +104,37 @@ main(int argc, char *argv[])
err(1, "execvp");
}
- /* find new window */
+ /* find window belonging to child */
+ for (i = 0; !w && i < MAX_LOOK; i++)
+ w = findwindow(child, XDefaultRootWindow(display));
+ if (!w)
+ die("could not find window\n");
- 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");
+ /* read from fifo */
+ if ((writefp = fopen(writefile, "r")) == NULL)
+ err(1, "fopen");
+ if ((cmd = malloc(MAX_CMD*sizeof(char))) == NULL)
+ err(1, "malloc");
line = NULL;
size = 0;
+
+ /* get first line and unlink fifo */
+ if ((len = getline(&line, &size, writefp)) == -1) goto end;
+ unlink(writefile);
+ goto loop;
+
+ /* process line and update title */
while ((len = getline(&line, &size, writefp)) != -1) {
- if (strncmp(line, "cwd", 3) == 0) {
- line += 3; line[len-4] = 0; /* chomp */
- cwd = wd(line);
+loop: if (strncmp(line, "cwd", 3) == 0) {
+ line[len-1] = 0;
+ line += 3;
+ cwd = cwdcpy(line);
XStoreName(display, w, cwd);
XFlush(display);
} else if (strncmp(line, "cmd", 3) == 0) {
- line += 3; line[len-4] = 0; /* chomp */
+ line[len-1] = 0;
+ line += 3;
if (strncmp(line, "fg", 2) != 0)
snprintf(cmd, MAX_CMD, "%s (%s)", line, cwd);
XStoreName(display, w, cmd);
@@ -131,6 +145,5 @@ main(int argc, char *argv[])
}
}
- unlink(writefile);
- XCloseDisplay(display);
+end: XCloseDisplay(display);
}