use stdio(3)
This commit is contained in:
		
							parent
							
								
									07d1edcd76
								
							
						
					
					
						commit
						a7f50ebb64
					
				
							
								
								
									
										95
									
								
								std.c
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								std.c
									
									
									
									
									
								
							| @ -15,6 +15,7 @@ | |||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <err.h> | #include <err.h> | ||||||
|  | #include <errno.h> | ||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) | #if !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) | ||||||
| #include <pty.h> | #include <pty.h> | ||||||
| @ -36,15 +37,8 @@ typedef struct { | |||||||
| 	int n; | 	int n; | ||||||
| } RingBuffer; | } RingBuffer; | ||||||
| 
 | 
 | ||||||
| typedef struct { |  | ||||||
| 	unsigned char data[BUFSIZ]; |  | ||||||
| 	int i, n; |  | ||||||
| 	int fd; |  | ||||||
| } ReadBuffer; |  | ||||||
| 
 |  | ||||||
| static void buffer(char c); | static void buffer(char c); | ||||||
| static void cmd(const char *cmdstr, ...); | static void cmd(const char *cmdstr, ...); | ||||||
| static int getch(ReadBuffer *buf); |  | ||||||
| static void getpty(void); | static void getpty(void); | ||||||
| static void movea(int x, int y); | static void movea(int x, int y); | ||||||
| static void mover(int x, int y); | static void mover(int x, int y); | ||||||
| @ -54,7 +48,6 @@ static void scroll(int l); | |||||||
| static void shell(void); | static void shell(void); | ||||||
| static void sigchld(int n); | static void sigchld(int n); | ||||||
| static char unbuffer(void); | static char unbuffer(void); | ||||||
| static void ungetch(ReadBuffer *buf, int c); |  | ||||||
| 
 | 
 | ||||||
| static int cols = 80, lines = 25; | static int cols = 80, lines = 25; | ||||||
| static int cx = 0, cy = 0; | static int cx = 0, cy = 0; | ||||||
| @ -63,7 +56,7 @@ static int ptm, pts; | |||||||
| static _Bool bold, digit, qmark; | static _Bool bold, digit, qmark; | ||||||
| static pid_t pid; | static pid_t pid; | ||||||
| static RingBuffer buf; | static RingBuffer buf; | ||||||
| static ReadBuffer cmdbuf, ptmbuf; | static FILE *fptm; | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| buffer(char c) { | buffer(char c) { | ||||||
| @ -86,17 +79,6 @@ cmd(const char *cmdstr, ...) { | |||||||
| 	va_end(ap); | 	va_end(ap); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int |  | ||||||
| getch(ReadBuffer *buf) { |  | ||||||
| 	if(buf->i++ >= buf->n) { |  | ||||||
| 		buf->n = read(buf->fd, buf->data, BUFSIZ); |  | ||||||
| 		if(buf->n == -1) |  | ||||||
| 			err(EXIT_FAILURE, "cannot read"); |  | ||||||
| 		buf->i = 0; |  | ||||||
| 	} |  | ||||||
| 	return buf->data[buf->i]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| movea(int x, int y) { | movea(int x, int y) { | ||||||
| 	x = MAX(x, cols); | 	x = MAX(x, cols); | ||||||
| @ -121,10 +103,10 @@ parseesc(void) { | |||||||
| 	int arg[16]; | 	int arg[16]; | ||||||
| 
 | 
 | ||||||
| 	memset(arg, 0, LENGTH(arg)); | 	memset(arg, 0, LENGTH(arg)); | ||||||
| 	c = getch(&ptmbuf); | 	c = getc(fptm); | ||||||
| 	switch(c) { | 	switch(c) { | ||||||
| 	case '[': | 	case '[': | ||||||
| 		c = getch(&ptmbuf); | 		c = getc(fptm); | ||||||
| 		for(j = 0; j < LENGTH(arg);) { | 		for(j = 0; j < LENGTH(arg);) { | ||||||
| 			if(isdigit(c)) { | 			if(isdigit(c)) { | ||||||
| 				digit = 1; | 				digit = 1; | ||||||
| @ -146,7 +128,7 @@ parseesc(void) { | |||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			c = getch(&ptmbuf); | 			c = getc(fptm); | ||||||
| 		} | 		} | ||||||
| 		switch(c) { | 		switch(c) { | ||||||
| 		case '@': | 		case '@': | ||||||
| @ -220,7 +202,7 @@ parseesc(void) { | |||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		putchar('\033'); | 		putchar('\033'); | ||||||
| 		ungetch(&ptmbuf, c); | 		ungetc(c, fptm); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -308,13 +290,6 @@ unbuffer(void) { | |||||||
| 	return c; | 	return c; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void |  | ||||||
| ungetch(ReadBuffer *buf, int c) { |  | ||||||
| 	if(buf->i + 1 >= buf->n) |  | ||||||
| 		errx(EXIT_FAILURE, "buffer full"); |  | ||||||
| 	buf->data[buf->i++] = c; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| int | int | ||||||
| main(int argc, char *argv[]) { | main(int argc, char *argv[]) { | ||||||
| 	fd_set rfds; | 	fd_set rfds; | ||||||
| @ -325,28 +300,31 @@ main(int argc, char *argv[]) { | |||||||
| 		errx(EXIT_FAILURE, "usage: std [-v]"); | 		errx(EXIT_FAILURE, "usage: std [-v]"); | ||||||
| 	getpty(); | 	getpty(); | ||||||
| 	shell(); | 	shell(); | ||||||
| 	cmdbuf.fd = STDIN_FILENO; |  | ||||||
| 	ptmbuf.fd = ptm; |  | ||||||
| 	FD_ZERO(&rfds); | 	FD_ZERO(&rfds); | ||||||
| 	FD_SET(STDIN_FILENO, &rfds); | 	FD_SET(STDIN_FILENO, &rfds); | ||||||
| 	FD_SET(ptm, &rfds); | 	FD_SET(ptm, &rfds); | ||||||
|  | 	if(!(fptm = fdopen(ptm, "r+"))) | ||||||
|  | 		err(EXIT_FAILURE, "cannot open pty"); | ||||||
|  | 	if(fcntl(ptm, F_SETFL, O_NONBLOCK) == -1) | ||||||
|  | 		err(EXIT_FAILURE, "cannot set pty to non-blocking mode"); | ||||||
|  | 	if(fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1) | ||||||
|  | 		err(EXIT_FAILURE, "cannot set stdin to non-blocking mode"); | ||||||
| 	for(;;) { | 	for(;;) { | ||||||
| 		if(select(ptm + 1, &rfds, NULL, NULL, NULL) == -1) | 		if(select(MAX(ptm, STDIN_FILENO) + 1, &rfds, NULL, NULL, NULL) == -1) | ||||||
| 			err(EXIT_FAILURE, "cannot select"); | 			err(EXIT_FAILURE, "cannot select"); | ||||||
| 		if(FD_ISSET(STDIN_FILENO, &rfds)) | 		if(FD_ISSET(ptm, &rfds)) { | ||||||
| 			do { | 			for(;;) { | ||||||
| 				c = getch(&cmdbuf); | 				if((c = getc(fptm)) == EOF) { | ||||||
| 				switch(c) { | 					if(feof(fptm)) { | ||||||
| 				case ':': | 						FD_CLR(ptm, &rfds); | ||||||
| 					parsecmd(); | 						fflush(fptm); | ||||||
| 					break; | 						break; | ||||||
| 				default: | 					} | ||||||
|  | 					if(errno != EAGAIN) | ||||||
|  | 						err(EXIT_FAILURE, "cannot read from pty"); | ||||||
|  | 					fflush(stdout); | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 			} while(cmdbuf.i < cmdbuf.n); |  | ||||||
| 		if(FD_ISSET(ptm, &rfds)) { |  | ||||||
| 			do { |  | ||||||
| 				c = getch(&ptmbuf); |  | ||||||
| 				switch(c) { | 				switch(c) { | ||||||
| 				case '\033': | 				case '\033': | ||||||
| 					parseesc(); | 					parseesc(); | ||||||
| @ -354,9 +332,32 @@ main(int argc, char *argv[]) { | |||||||
| 				default: | 				default: | ||||||
| 					putchar(c); | 					putchar(c); | ||||||
| 				} | 				} | ||||||
| 			} while(ptmbuf.i < ptmbuf.n); | 			} | ||||||
| 			fflush(stdout); | 			fflush(stdout); | ||||||
| 		} | 		} | ||||||
|  | 		if(FD_ISSET(STDIN_FILENO, &rfds)) { | ||||||
|  | 			for(;;) { | ||||||
|  | 				if((c = getchar()) == EOF) { | ||||||
|  | 					if(feof(stdin)) { | ||||||
|  | 						FD_CLR(STDIN_FILENO, &rfds); | ||||||
|  | 						fflush(fptm); | ||||||
|  | 						break; | ||||||
|  | 					} | ||||||
|  | 					if(errno != EAGAIN) | ||||||
|  | 						err(EXIT_FAILURE, "cannot read from stdin"); | ||||||
|  | 					fflush(fptm); | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 				switch(c) { | ||||||
|  | 				case ':': | ||||||
|  | 					parsecmd(); | ||||||
|  | 					break; | ||||||
|  | 				default: | ||||||
|  | 					putc(c, fptm); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			fflush(fptm); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Matthias-Christian Ott
						Matthias-Christian Ott