diff --git a/CHANGES b/CHANGES index d31b8eaf..fcc7e7fb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,6 @@ 26 January 2009 +* Be more clever about picking the right process to create the window name. * Don't balls up the terminal on UTF-8 combined characters. Don't support them properly either - they are just discarded for the moment. @@ -1013,7 +1014,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.235 2009-01-26 20:57:42 nicm Exp $ +$Id: CHANGES,v 1.236 2009-01-26 22:57:18 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/names.c b/names.c index fe7eef3b..4e6eba63 100644 --- a/names.c +++ b/names.c @@ -1,4 +1,4 @@ -/* $Id: names.c,v 1.1 2009-01-20 19:35:03 nicm Exp $ */ +/* $Id: names.c,v 1.2 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -31,8 +31,7 @@ set_window_names(void) { struct window *w; u_int i; - pid_t pgrp; - char *name; + char *name, *wname; struct timeval tv, tv2; if (gettimeofday(&tv, NULL) != 0) @@ -53,21 +52,20 @@ set_window_names(void) timeradd(&w->name_timer, &tv2, &w->name_timer); if (w->active->screen != &w->active->base) - pgrp = -1; - else if ((pgrp = tcgetpgrp(w->active->fd)) == w->pgrp) - continue; - w->pgrp = pgrp; - - name = get_argv0(pgrp); - if (pgrp == -1 || name == NULL) - name = default_window_name(w); + name = NULL; else - name = parse_window_name(name); - if (strcmp(name, w->name) == 0) + name = get_argv0(w->active->fd, w->active->tty); + if (name == NULL) + wname = default_window_name(w); + else { + wname = parse_window_name(name); xfree(name); + } + if (strcmp(wname, w->name) == 0) + xfree(wname); else { xfree(w->name); - w->name = name; + w->name = wname; server_status_window(w); } } diff --git a/osdep-darwin.c b/osdep-darwin.c index 653b52fe..5f768cbb 100644 --- a/osdep-darwin.c +++ b/osdep-darwin.c @@ -1,4 +1,4 @@ -/* $Id: osdep-darwin.c,v 1.1 2009-01-20 22:17:53 nicm Exp $ */ +/* $Id: osdep-darwin.c,v 1.2 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2009 Joshua Elsasser @@ -23,7 +23,7 @@ #include -char *get_argv0(pid_t); +char *get_argv0(int, char *); /* * XXX This actually returns the executable path, not the process's argv[0]. @@ -32,13 +32,15 @@ char *get_argv0(pid_t); */ char * -get_argv0(pid_t pgrp) +get_argv0(int fd, __attribute__ ((unused)) char *tty) { int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 }; size_t size; struct kinfo_proc kp; - mib[3] = pgrp; + if ((mib[3] = tcgetpgrp(fd)) == -1) + return (NULL) + size = sizeof kp; if (sysctl(mib, 4, &kp, &size, NULL, 0) == -1 || kp.kp_proc.p_comm[0] == '\0') diff --git a/osdep-freebsd.c b/osdep-freebsd.c index 0e04a4c0..3a495d4a 100644 --- a/osdep-freebsd.c +++ b/osdep-freebsd.c @@ -1,4 +1,4 @@ -/* $Id: osdep-freebsd.c,v 1.2 2009-01-20 22:17:53 nicm Exp $ */ +/* $Id: osdep-freebsd.c,v 1.3 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -19,7 +19,10 @@ #ifdef __FreeBSD__ #include +#include +#include #include +#include #include #include @@ -28,19 +31,80 @@ #include #include -char *get_argv0(pid_t); +char *get_argv0(int, char *); +char *get_proc_argv0(pid_t); + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) char * -get_argv0(pid_t pgrp) +get_argv0(__attribute__ ((unused)) int fd, char *tty) +{ + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_TTY, 0 }; + struct stat sb; + size_t len; + struct kinfo_proc *buf, *newbuf, *p, *bestp; + char *procname; + u_int i; + + buf = NULL; + + if (stat(tty, &sb) == -1) + return (NULL); + mib[3] = sb.st_rdev; + +retry: + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1) + return (NULL); + len = (len * 5) / 4; + + if ((newbuf = realloc(buf, len)) == NULL) { + free(buf); + return (NULL); + } + buf = newbuf; + + if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) { + if (errno == ENOMEM) + goto retry; + free(buf); + return (NULL); + } + + bestp = NULL; + for (i = 0; i < len / sizeof (struct kinfo_proc); i++) { + p = &buf[i]; + if (bestp == NULL) + bestp = p; + + if (p->ki_stat != SRUN && p->ki_stat != SIDL) + continue; + if (p->ki_estcpu < bestp->ki_estcpu) + continue; + if (p->ki_slptime > bestp->ki_slptime) + continue; + bestp = p; + } + + procname = get_proc_argv0(bestp->ki_pid); + if (procname == NULL || *procname == '\0') { + free(procname); + procname = strdup(bestp->ki_comm); + } + + free(buf); + return (procname); +} + +char * +get_proc_argv0(pid_t pid) { int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, 0 }; size_t size; char *args, *args2, *procname; + mib[3] = pid; procname = NULL; - mib[3] = pgrp; - args = NULL; size = 128; while (size < SIZE_MAX / 2) { diff --git a/osdep-linux.c b/osdep-linux.c index b2a68459..986b8d8e 100644 --- a/osdep-linux.c +++ b/osdep-linux.c @@ -1,4 +1,4 @@ -/* $Id: osdep-linux.c,v 1.1 2009-01-20 19:35:03 nicm Exp $ */ +/* $Id: osdep-linux.c,v 1.2 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -27,16 +27,23 @@ #include "tmux.h" char * -get_argv0(pid_t pgrp) +get_argv0(int fd, unused char *tty) { FILE *f; char *path, *buf; size_t len; int ch; + pid_t pgrp; + + if ((pgrp = tcgetpgrp(fd)) == -1) + return (NULL); xasprintf(&path, "/proc/%lld/cmdline", (long long) pgrp); - if ((f = fopen(path, "r")) == NULL) + if ((f = fopen(path, "r")) == NULL) { + xfree(path); return (NULL); + } + xfree(path); len = 0; buf = NULL; diff --git a/osdep-openbsd.c b/osdep-openbsd.c index 6c39416d..e35a355a 100644 --- a/osdep-openbsd.c +++ b/osdep-openbsd.c @@ -1,4 +1,4 @@ -/* $Id: osdep-openbsd.c,v 1.2 2009-01-20 22:17:53 nicm Exp $ */ +/* $Id: osdep-openbsd.c,v 1.3 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -27,10 +28,73 @@ #include #include -char *get_argv0(pid_t); +char *get_argv0(int, char *); +char *get_proc_argv0(pid_t); char * -get_argv0(pid_t pgrp) +get_argv0(__attribute__ ((unused)) int fd, char *tty) +{ + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_TTY, 0 }; + struct stat sb; + size_t len; + struct kinfo_proc *buf, *newbuf; + struct proc *p, *bestp; + char *procname; + u_int i; + + buf = NULL; + + if (stat(tty, &sb) == -1) + return (NULL); + mib[3] = sb.st_rdev; + +retry: + if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1) + return (NULL); + len = (len * 5) / 4; + + if ((newbuf = realloc(buf, len)) == NULL) { + free(buf); + return (NULL); + } + buf = newbuf; + + if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) { + if (errno == ENOMEM) + goto retry; + free(buf); + return (NULL); + } + + bestp = NULL; + for (i = 0; i < len / sizeof (struct kinfo_proc); i++) { + p = &buf[i].kp_proc; + if (bestp == NULL) + bestp = p; + + if (p->p_stat != SRUN && + p->p_stat != SIDL && + p->p_stat != SONPROC) + continue; + if (p->p_estcpu < bestp->p_estcpu) + continue; + if (p->p_slptime > bestp->p_slptime) + continue; + bestp = p; + } + + procname = get_proc_argv0(bestp->p_pid); + if (procname == NULL || *procname == '\0') { + free(procname); + procname = strdup(bestp->p_comm); + } + + free(buf); + return (procname); +} + +char * +get_proc_argv0(pid_t pid) { int mib[4] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ARGV }; size_t size; @@ -38,7 +102,7 @@ get_argv0(pid_t pgrp) procname = NULL; - mib[2] = pgrp; + mib[2] = pid; args = NULL; size = 128; diff --git a/tmux.h b/tmux.h index 4a018911..45c00102 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.250 2009-01-25 19:00:10 tcunha Exp $ */ +/* $Id: tmux.h,v 1.251 2009-01-26 22:57:19 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -140,7 +140,7 @@ extern const char *__progname; #define printflike4 __attribute__ ((format (printf, 4, 5))) /* Number of items in array. */ -#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) /* Buffer macros. */ #define BUFFER_USED(b) ((b)->size) @@ -592,6 +592,7 @@ struct window_pane { char *cwd; int fd; + char tty[TTY_NAME_MAX]; struct buffer *in; struct buffer *out; @@ -1503,7 +1504,7 @@ int utf8_width(u_int); char *section_string(char *, size_t, size_t, size_t); /* osdep-*.c */ -char *get_argv0(pid_t); +char *get_argv0(int, char *); /* buffer.c */ struct buffer *buffer_create(size_t); diff --git a/window.c b/window.c index 9eb96e25..76dd1960 100644 --- a/window.c +++ b/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.62 2009-01-23 16:59:14 nicm Exp $ */ +/* $Id: window.c,v 1.63 2009-01-26 22:57:20 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -569,7 +569,7 @@ window_pane_spawn(struct window_pane *wp, tv.tv_usec = NAME_INTERVAL * 1000L; timeradd(&wp->window->name_timer, &tv, &wp->window->name_timer); - switch (forkpty(&wp->fd, NULL, NULL, &ws)) { + switch (forkpty(&wp->fd, wp->tty, NULL, &ws)) { case -1: wp->fd = -1; xasprintf(cause, "%s: %s", cmd, strerror(errno));