/* * safetitle sets the title of the terminal window to the given string, * if and only if the terminal is recognized via its device attributes. * * If multiple terminals are attached to the same GNU screen session, * the title is not set. It is theoretically possible to check every * terminal too see if it is recognized and, if so, set the title -- * but that would make the code more complex. */ #include #include #include #include #include #include #include #include #define WSCONS_DA (char[]){27,91,62,50,52,59,50,48,59,48,99,0} #define SCREEN_DA (char[]){27,91,62,56,51,59,52,48,56,48,48,59,48,99,0} int debug = 0; int da(int fd, char *buf, int real) { char c; fd_set fds; int i, r, responses; struct timeval timeout; FD_ZERO(&fds); FD_SET(fd, &fds); timeout.tv_sec = 0; timeout.tv_usec = 1; responses = 0; i = 0; if(real) write(fd, "\033P\033[>c\033\\", 8); else write(fd, "\033[>c", 4); while(r = read(fd, &c, 1)){ loop: if(r==-1){ warn("read"); return -1; } buf[i++] = c; if(c==99) break; } buf[i] = '\0'; responses++; /* ensure there is only one real terminal */ check: if(real && select(fd+1, &fds, NULL, NULL, &timeout)>0){ if ((r = read(fd, &c, 1)) && c==0) goto check; /* extra nul */ else goto loop; } if(responses>1){ if(debug) fprintf(stderr, "more than one attached terminal\n"); return -1; } return i; } int main(int argc, char *argv[]) { char *ap, *buf; int r, screen, ttyfd; struct termios term, restore; r = 1; /* parse arguments */ if(argc==2) ap = argv[1]; else if(argc==3){ ap = argv[2]; if(strcmp(argv[1], "-d")==0) debug = 1; else goto usage; } else goto usage; if((ttyfd = open("/dev/tty", O_RDWR))==-1) err(1, "open"); if((buf = malloc(200*sizeof(char)))==NULL) err(1, "malloc"); /* enter "raw" terminal mode */ tcgetattr(ttyfd, &restore); tcgetattr(ttyfd, &term); term.c_lflag &= ~(ICANON|ECHO); tcsetattr(ttyfd, TCSANOW, &term); /* get device attributes for real terminal */ if(da(ttyfd, buf, 0)==-1){ goto end; } screen = strcmp(buf, SCREEN_DA)==0; if(screen && da(ttyfd, buf, screen)==-1){ goto end; } /* set title */ if(strcmp(buf, WSCONS_DA)==0){ if(debug) fprintf(stderr, "wrong type of terminal\n"); goto end; } else{ if(screen) dprintf(ttyfd, "\033P\033]2;%s\007\033\\", ap); else dprintf(ttyfd, "\033]2;%s\007", ap); } r = 0; end: tcsetattr(ttyfd, TCSANOW, &restore); return r; usage: fprintf(stderr, "usage: %s [-d] title\n", argv[0]); return 1; }