diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | termsettitle.c | 101 |
2 files changed, 107 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..31132bb --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +CFLAGS += -O2 -pedantic -Wall -Wextra + +termsettitle: termsettitle.c + +install: + install termsettitle /usr/local/bin diff --git a/termsettitle.c b/termsettitle.c new file mode 100644 index 0000000..8ef7d10 --- /dev/null +++ b/termsettitle.c @@ -0,0 +1,101 @@ +/* + * termsettitle sets the title of the terminal window to the given string, + * if and only if the terminal is recognized via its device attributes. + * + * Note that this does NOT (yet) work inside GNU screen if several terminals + * are attached to the same session. + * (Maybe we could try to read again, but with a timeout? If there is more + * to read, we read it and then abort.) + * (Or maybe there IS a way to check if there is something to read.) + */ + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#define XTERM_DA (char[]){27,91,62,52,49,59,51,51,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 +da(int fd, char *buf, int real) +{ + int c, i, r; + i = 0; + if(real) write(fd, "\033P\033[>c\033\\", 8); + else write(fd, "\033[>c", 4); + while(r = read(fd, &c, 1)){ + if(!r){ + fprintf(stderr, "bad terminal\n"); + return -1; + } + buf[i] = c; + if(c==99){ + buf[++i] = '\0'; + return i; + } + i++; + } + return i; +} + +int +main(int argc, char *argv[]) +{ + char *ap, *buf; + int debug, screen, ttyfd; + struct termios term, restore; + + /* parse arguments */ + debug = 0; + 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 fail; + if(strcmp(buf, SCREEN_DA)==0) + screen = 1; + else + screen = 0; + if(da(ttyfd, buf, screen)==-1) goto fail; + + /* set title */ + if(strcmp(buf, XTERM_DA)==0){ + if(screen) dprintf(ttyfd, "\033P\033]2;%s\007\033\\", ap); + dprintf(ttyfd, "\033]2;%s\007", ap); + } + else{ + if(debug) fprintf(stderr, "wrong type of terminal\n"); + goto fail; + } + + tcsetattr(ttyfd, TCSANOW, &restore); + exit(0); + +fail: + tcsetattr(ttyfd, TCSANOW, &restore); + exit(1); +usage: + fprintf(stderr, "usage: %s [-d] title\n", argv[0]); + exit(1); +} |