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 | } |