diff options
| author | Matthias-Christian Ott <ott@enolink.de> | 2008-08-25 17:56:00 +0200 |
|---|---|---|
| committer | Matthias-Christian Ott <ott@enolink.de> | 2008-08-25 17:56:00 +0200 |
| commit | a7f50ebb64892900e5b56e30c6edd83807a4040b (patch) | |
| tree | 59aa30054fb8cfa0c58e6cc84be58e52679f8b29 | |
| parent | 07d1edcd76cf8ec3f6e72e79bbc1481da77e30f7 (diff) | |
| download | st-a7f50ebb64892900e5b56e30c6edd83807a4040b.tar.gz st-a7f50ebb64892900e5b56e30c6edd83807a4040b.zip | |
use stdio(3)
| -rw-r--r-- | std.c | 95 |
1 files changed, 48 insertions, 47 deletions
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <sys/wait.h> | 15 | #include <sys/wait.h> |
| 16 | #include <ctype.h> | 16 | #include <ctype.h> |
| 17 | #include <err.h> | 17 | #include <err.h> |
| 18 | #include <errno.h> | ||
| 18 | #include <fcntl.h> | 19 | #include <fcntl.h> |
| 19 | #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) | 20 | #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) |
| 20 | #include <pty.h> | 21 | #include <pty.h> |
| @@ -36,15 +37,8 @@ typedef struct { | |||
| 36 | int n; | 37 | int n; |
| 37 | } RingBuffer; | 38 | } RingBuffer; |
| 38 | 39 | ||
| 39 | typedef struct { | ||
| 40 | unsigned char data[BUFSIZ]; | ||
| 41 | int i, n; | ||
| 42 | int fd; | ||
| 43 | } ReadBuffer; | ||
| 44 | |||
| 45 | static void buffer(char c); | 40 | static void buffer(char c); |
| 46 | static void cmd(const char *cmdstr, ...); | 41 | static void cmd(const char *cmdstr, ...); |
| 47 | static int getch(ReadBuffer *buf); | ||
| 48 | static void getpty(void); | 42 | static void getpty(void); |
| 49 | static void movea(int x, int y); | 43 | static void movea(int x, int y); |
| 50 | static void mover(int x, int y); | 44 | static void mover(int x, int y); |
| @@ -54,7 +48,6 @@ static void scroll(int l); | |||
| 54 | static void shell(void); | 48 | static void shell(void); |
| 55 | static void sigchld(int n); | 49 | static void sigchld(int n); |
| 56 | static char unbuffer(void); | 50 | static char unbuffer(void); |
| 57 | static void ungetch(ReadBuffer *buf, int c); | ||
| 58 | 51 | ||
| 59 | static int cols = 80, lines = 25; | 52 | static int cols = 80, lines = 25; |
| 60 | static int cx = 0, cy = 0; | 53 | static int cx = 0, cy = 0; |
| @@ -63,7 +56,7 @@ static int ptm, pts; | |||
| 63 | static _Bool bold, digit, qmark; | 56 | static _Bool bold, digit, qmark; |
| 64 | static pid_t pid; | 57 | static pid_t pid; |
| 65 | static RingBuffer buf; | 58 | static RingBuffer buf; |
| 66 | static ReadBuffer cmdbuf, ptmbuf; | 59 | static FILE *fptm; |
| 67 | 60 | ||
| 68 | void | 61 | void |
| 69 | buffer(char c) { | 62 | buffer(char c) { |
| @@ -86,17 +79,6 @@ cmd(const char *cmdstr, ...) { | |||
| 86 | va_end(ap); | 79 | va_end(ap); |
| 87 | } | 80 | } |
| 88 | 81 | ||
| 89 | int | ||
| 90 | getch(ReadBuffer *buf) { | ||
| 91 | if(buf->i++ >= buf->n) { | ||
| 92 | buf->n = read(buf->fd, buf->data, BUFSIZ); | ||
| 93 | if(buf->n == -1) | ||
| 94 | err(EXIT_FAILURE, "cannot read"); | ||
| 95 | buf->i = 0; | ||
| 96 | } | ||
| 97 | return buf->data[buf->i]; | ||
| 98 | } | ||
| 99 | |||
| 100 | void | 82 | void |
| 101 | movea(int x, int y) { | 83 | movea(int x, int y) { |
| 102 | x = MAX(x, cols); | 84 | x = MAX(x, cols); |
| @@ -121,10 +103,10 @@ parseesc(void) { | |||
| 121 | int arg[16]; | 103 | int arg[16]; |
| 122 | 104 | ||
| 123 | memset(arg, 0, LENGTH(arg)); | 105 | memset(arg, 0, LENGTH(arg)); |
| 124 | c = getch(&ptmbuf); | 106 | c = getc(fptm); |
| 125 | switch(c) { | 107 | switch(c) { |
| 126 | case '[': | 108 | case '[': |
| 127 | c = getch(&ptmbuf); | 109 | c = getc(fptm); |
| 128 | for(j = 0; j < LENGTH(arg);) { | 110 | for(j = 0; j < LENGTH(arg);) { |
| 129 | if(isdigit(c)) { | 111 | if(isdigit(c)) { |
| 130 | digit = 1; | 112 | digit = 1; |
| @@ -146,7 +128,7 @@ parseesc(void) { | |||
| 146 | } | 128 | } |
| 147 | break; | 129 | break; |
| 148 | } | 130 | } |
| 149 | c = getch(&ptmbuf); | 131 | c = getc(fptm); |
| 150 | } | 132 | } |
| 151 | switch(c) { | 133 | switch(c) { |
| 152 | case '@': | 134 | case '@': |
| @@ -220,7 +202,7 @@ parseesc(void) { | |||
| 220 | break; | 202 | break; |
| 221 | default: | 203 | default: |
| 222 | putchar('\033'); | 204 | putchar('\033'); |
| 223 | ungetch(&ptmbuf, c); | 205 | ungetc(c, fptm); |
| 224 | } | 206 | } |
| 225 | } | 207 | } |
| 226 | 208 | ||
| @@ -308,13 +290,6 @@ unbuffer(void) { | |||
| 308 | return c; | 290 | return c; |
| 309 | } | 291 | } |
| 310 | 292 | ||
| 311 | void | ||
| 312 | ungetch(ReadBuffer *buf, int c) { | ||
| 313 | if(buf->i + 1 >= buf->n) | ||
| 314 | errx(EXIT_FAILURE, "buffer full"); | ||
| 315 | buf->data[buf->i++] = c; | ||
| 316 | } | ||
| 317 | |||
| 318 | int | 293 | int |
| 319 | main(int argc, char *argv[]) { | 294 | main(int argc, char *argv[]) { |
| 320 | fd_set rfds; | 295 | fd_set rfds; |
| @@ -325,28 +300,31 @@ main(int argc, char *argv[]) { | |||
| 325 | errx(EXIT_FAILURE, "usage: std [-v]"); | 300 | errx(EXIT_FAILURE, "usage: std [-v]"); |
| 326 | getpty(); | 301 | getpty(); |
| 327 | shell(); | 302 | shell(); |
| 328 | cmdbuf.fd = STDIN_FILENO; | ||
| 329 | ptmbuf.fd = ptm; | ||
| 330 | FD_ZERO(&rfds); | 303 | FD_ZERO(&rfds); |
| 331 | FD_SET(STDIN_FILENO, &rfds); | 304 | FD_SET(STDIN_FILENO, &rfds); |
| 332 | FD_SET(ptm, &rfds); | 305 | FD_SET(ptm, &rfds); |
| 306 | if(!(fptm = fdopen(ptm, "r+"))) | ||
| 307 | err(EXIT_FAILURE, "cannot open pty"); | ||
| 308 | if(fcntl(ptm, F_SETFL, O_NONBLOCK) == -1) | ||
| 309 | err(EXIT_FAILURE, "cannot set pty to non-blocking mode"); | ||
| 310 | if(fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) | ||
| 311 | err(EXIT_FAILURE, "cannot set stdin to non-blocking mode"); | ||
| 333 | for(;;) { | 312 | for(;;) { |
| 334 | if(select(ptm + 1, &rfds, NULL, NULL, NULL) == -1) | 313 | if(select(MAX(ptm, STDIN_FILENO) + 1, &rfds, NULL, NULL, NULL) == -1) |
| 335 | err(EXIT_FAILURE, "cannot select"); | 314 | err(EXIT_FAILURE, "cannot select"); |
| 336 | if(FD_ISSET(STDIN_FILENO, &rfds)) | 315 | if(FD_ISSET(ptm, &rfds)) { |
| 337 | do { | 316 | for(;;) { |
| 338 | c = getch(&cmdbuf); | 317 | if((c = getc(fptm)) == EOF) { |
| 339 | switch(c) { | 318 | if(feof(fptm)) { |
| 340 | case ':': | 319 | FD_CLR(ptm, &rfds); |
| 341 | parsecmd(); | 320 | fflush(fptm); |
| 342 | break; | 321 | break; |
| 343 | default: | 322 | } |
| 323 | if(errno != EAGAIN) | ||
| 324 | err(EXIT_FAILURE, "cannot read from pty"); | ||
| 325 | fflush(stdout); | ||
| 344 | break; | 326 | break; |
| 345 | } | 327 | } |
| 346 | } while(cmdbuf.i < cmdbuf.n); | ||
| 347 | if(FD_ISSET(ptm, &rfds)) { | ||
| 348 | do { | ||
| 349 | c = getch(&ptmbuf); | ||
| 350 | switch(c) { | 328 | switch(c) { |
| 351 | case '\033': | 329 | case '\033': |
| 352 | parseesc(); | 330 | parseesc(); |
| @@ -354,9 +332,32 @@ main(int argc, char *argv[]) { | |||
| 354 | default: | 332 | default: |
| 355 | putchar(c); | 333 | putchar(c); |
| 356 | } | 334 | } |
| 357 | } while(ptmbuf.i < ptmbuf.n); | 335 | } |
| 358 | fflush(stdout); | 336 | fflush(stdout); |
| 359 | } | 337 | } |
| 338 | if(FD_ISSET(STDIN_FILENO, &rfds)) { | ||
| 339 | for(;;) { | ||
| 340 | if((c = getchar()) == EOF) { | ||
| 341 | if(feof(stdin)) { | ||
| 342 | FD_CLR(STDIN_FILENO, &rfds); | ||
| 343 | fflush(fptm); | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | if(errno != EAGAIN) | ||
| 347 | err(EXIT_FAILURE, "cannot read from stdin"); | ||
| 348 | fflush(fptm); | ||
| 349 | break; | ||
| 350 | } | ||
| 351 | switch(c) { | ||
| 352 | case ':': | ||
| 353 | parsecmd(); | ||
| 354 | break; | ||
| 355 | default: | ||
| 356 | putc(c, fptm); | ||
| 357 | } | ||
| 358 | } | ||
| 359 | fflush(fptm); | ||
| 360 | } | ||
| 360 | } | 361 | } |
| 361 | return 0; | 362 | return 0; |
| 362 | } | 363 | } |
