diff options
Diffstat (limited to 'safetitle.c')
-rw-r--r-- | safetitle.c | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/safetitle.c b/safetitle.c index bf73e2c..9004b03 100644 --- a/safetitle.c +++ b/safetitle.c @@ -1,11 +1,6 @@ /* * 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 <err.h> @@ -17,60 +12,95 @@ #include <termios.h> #include <unistd.h> +#define WSCONS 0 +#define SCREEN 1 + #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 screen = 0; int -da(int fd, char *buf, int real) +blacklisted(int fd) { - char c; + char *buf, c; fd_set fds; - int i, r, responses; + int i, r; struct timeval timeout; + /* setup */ + if((buf = malloc(200*sizeof(char)))==NULL) + err(1, "malloc"); + + /* check if GNU screen */ + write(fd, "\033[>c", 4); + i = 0; + while(r = read(fd, &c, 1)){ + if(r==-1){ + warn("read"); + return 1; + } + buf[i++] = c; + if(c=='c') break; + } + buf[i] = '\0'; + screen = strcmp(buf, SCREEN_DA)==0; + FD_ZERO(&fds); FD_SET(fd, &fds); timeout.tv_sec = 0; - timeout.tv_usec = 1; - responses = 0; - i = 0; + timeout.tv_usec = 0; + + /* ignore strange trailing nul */ + while(select(fd+1, &fds, NULL, NULL, &timeout)>0) + read(fd, &c, 1); - if(real) write(fd, "\033P\033[>c\033\\", 8); + /* check (real) terminal type(s) */ + if(screen) write(fd, "\033P\033[>c\033\\", 8); else write(fd, "\033[>c", 4); + i = 0; while(r = read(fd, &c, 1)){ loop: if(r==-1){ warn("read"); - return -1; + return 1; } buf[i++] = c; if(c==99) break; } buf[i] = '\0'; - responses++; - /* ensure there is only one real terminal */ + if(strcmp(buf, WSCONS_DA)==0){ + if(debug) fprintf(stderr, "blacklisted terminal type\n"); + return 1; + } + + /* go back and check remaining responses (if any) */ check: - if(real && select(fd+1, &fds, NULL, NULL, &timeout)>0){ - if ((r = read(fd, &c, 1)) && c==0) goto check; /* extra nul */ + FD_ZERO(&fds); + FD_SET(fd, &fds); + timeout.tv_sec = 0; + timeout.tv_usec = 1; + if(screen && select(fd+1, &fds, NULL, NULL, &timeout)>0){ + i = 0; + if(read(fd, &c, 1)==-1){ + warn("read"); + return 1; + } + if(c==0) goto check; /* ignore strange trailing nul */ else goto loop; } - if(responses>1){ - if(debug) fprintf(stderr, "more than one attached terminal\n"); - return -1; - } - return i; + return 0; } int main(int argc, char *argv[]) { - char *ap, *buf; - int screen, ttyfd; + char *ap; + int ttyfd; struct termios term, restore; /* parse arguments */ @@ -85,8 +115,6 @@ main(int argc, char *argv[]) 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); @@ -95,23 +123,12 @@ main(int argc, char *argv[]) tcsetattr(ttyfd, TCSANOW, &term); /* get device attributes for real terminal */ - if(da(ttyfd, buf, 0)==-1){ + if(blacklisted(ttyfd)) 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); - } + if(screen) dprintf(ttyfd, "\033P\033]2;%s\007\033\\", ap); + else dprintf(ttyfd, "\033]2;%s\007", ap); tcsetattr(ttyfd, TCSANOW, &restore); return 0; |