1 /* $OpenBSD: names.c,v 1.8 2009/10/10 15:23:13 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 21 #include <ctype.h> 22 #include <libgen.h> 23 #include <string.h> 24 #include <unistd.h> 25 26 #include "tmux.h" 27 28 char *parse_window_name(const char *); 29 30 void 31 set_window_names(void) 32 { 33 struct window *w; 34 u_int i; 35 char *name, *wname; 36 struct timeval tv, tv2; 37 38 if (gettimeofday(&tv, NULL) != 0) 39 fatal("gettimeofday failed"); 40 41 for (i = 0; i < ARRAY_LENGTH(&windows); i++) { 42 w = ARRAY_ITEM(&windows, i); 43 if (w == NULL || w->active == NULL) 44 continue; 45 46 if (timercmp(&tv, &w->name_timer, <)) 47 continue; 48 memcpy(&w->name_timer, &tv, sizeof w->name_timer); 49 tv2.tv_sec = 0; 50 tv2.tv_usec = NAME_INTERVAL * 1000L; 51 timeradd(&w->name_timer, &tv2, &w->name_timer); 52 53 if (!options_get_number(&w->options, "automatic-rename")) 54 continue; 55 56 if (w->active->screen != &w->active->base) 57 name = NULL; 58 else 59 name = get_proc_name(w->active->fd, w->active->tty); 60 if (name == NULL) 61 wname = default_window_name(w); 62 else { 63 /* 64 * If tmux is using the default command, it will be a 65 * login shell and argv[0] may have a - prefix. Remove 66 * this if it is present. Ick. 67 */ 68 if (w->active->cmd != NULL && *w->active->cmd == '\0' && 69 name != NULL && name[0] == '-' && name[1] != '\0') 70 wname = parse_window_name(name + 1); 71 else 72 wname = parse_window_name(name); 73 xfree(name); 74 } 75 76 if (w->active->fd == -1) { 77 xasprintf(&name, "%s[dead]", wname); 78 xfree(wname); 79 wname = name; 80 } 81 82 if (strcmp(wname, w->name) == 0) 83 xfree(wname); 84 else { 85 xfree(w->name); 86 w->name = wname; 87 server_status_window(w); 88 } 89 } 90 } 91 92 char * 93 default_window_name(struct window *w) 94 { 95 if (w->active->screen != &w->active->base) 96 return (xstrdup("[tmux]")); 97 if (w->active->cmd != NULL && *w->active->cmd != '\0') 98 return (parse_window_name(w->active->cmd)); 99 return (parse_window_name(w->active->shell)); 100 } 101 102 char * 103 parse_window_name(const char *in) 104 { 105 char *copy, *name, *ptr; 106 107 name = copy = xstrdup(in); 108 if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) 109 name = name + (sizeof "exec ") - 1; 110 111 while (*name == ' ') 112 name++; 113 if ((ptr = strchr(name, ' ')) != NULL) 114 *ptr = '\0'; 115 116 if (*name != '\0') { 117 ptr = name + strlen(name) - 1; 118 while (ptr > name && !isalnum((u_char)*ptr)) 119 *ptr-- = '\0'; 120 } 121 122 if (*name == '/') 123 name = basename(name); 124 name = xstrdup(name); 125 xfree(copy); 126 return (name); 127 } 128