diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/conswdir.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/conswdir.c')
-rwxr-xr-x | sys/src/cmd/aux/conswdir.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/conswdir.c b/sys/src/cmd/aux/conswdir.c new file mode 100755 index 000000000..842d400d7 --- /dev/null +++ b/sys/src/cmd/aux/conswdir.c @@ -0,0 +1,181 @@ +/* + * Process in-band messages about window title changes. + * The messages are of the form: + * + * \033];xxx\007 + * + * where xxx is the new directory. This format was chosen + * because it changes the label on xterm windows. + */ + +#include <u.h> +#include <libc.h> + +struct { + char *file; + char name[512]; +} keep[] = { + { "/dev/label" }, + { "/dev/wdir" } +}; + +char *prog = "/bin/rwd"; + +void +usage(void) +{ + fprint(2, "usage: conswdir [/bin/rwd]\n"); + exits("usage"); +} + +void +save(void) +{ + int i, fd; + for(i = 0; i < nelem(keep); i++){ + *keep[i].name = 0; + if((fd = open(keep[i].file, OREAD)) != -1){ + read(fd, keep[i].name, sizeof(keep[i].name)); + close(fd); + } + } +} + +void +rest(void) +{ + int i, fd; + for(i = 0; i < nelem(keep); i++) + if((fd = open(keep[i].file, OWRITE)) != -1){ + write(fd, keep[i].name, strlen(keep[i].name)); + close(fd); + } + +} + +void +setpath(char *s) +{ + switch(rfork(RFPROC|RFFDG|RFNOWAIT)){ + case 0: + execl(prog, prog, s, nil); + _exits(nil); + } +} + +enum +{ + None, + Esc, + Brack, + Semi, + Bell, +}; + +int +process(char *buf, int n, int *pn) +{ + char *p; + char path[4096]; + int start, state; + + start = 0; + state = None; + for(p=buf; p<buf+n; p++){ + switch(state){ + case None: + if(*p == '\033'){ + start = p-buf; + state++; + } + break; + case Esc: + if(*p == ']') + state++; + else + state = None; + break; + case Brack: + if(*p == ';') + state++; + else + state = None; + break; + case Semi: + if(*p == '\007') + state++; + else if((uchar)*p < 040) + state = None; + break; + } + if(state == Bell){ + memmove(path, buf+start+3, p - (buf+start+3)); + path[p-(buf+start+3)] = 0; + p++; + memmove(buf+start, p, n-(p-buf)); + n -= p-(buf+start); + p = buf+start; + p--; + start = 0; + state = None; + setpath(path); + } + } + /* give up if we go too long without seeing the close */ + *pn = n; + if(state == None || p-(buf+start) >= 2048) + return (p - buf); + else + return start; +} + +static void +catchint(void*, char *msg) +{ + if(strstr(msg, "interrupt")) + noted(NCONT); + else if(strstr(msg, "kill")) + noted(NDFLT); + else + noted(NCONT); +} + +void +main(int argc, char **argv) +{ + char buf[4096]; + int n, m; + + notify(catchint); + + ARGBEGIN{ + default: + usage(); + }ARGEND + + if(argc > 1) + usage(); + if(argc == 1) + prog = argv[0]; + + save(); + n = 0; + for(;;){ + m = read(0, buf+n, sizeof buf-n); + if(m < 0){ + rerrstr(buf, sizeof buf); + if(strstr(buf, "interrupt")) + continue; + break; + } + n += m; + m = process(buf, n, &n); + if(m > 0){ + write(1, buf, m); + memmove(buf, buf+m, n-m); + n -= m; + } + } + rest(); + exits(nil); +} |