use stdio(3)
This commit is contained in:
		
							
								
								
									
										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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user