aboutsummaryrefslogtreecommitdiff
path: root/rio.c
blob: a36af2b7b7b8a1d69367383941a1e31f0f88701c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <unistd.h>

#define MAXBUF 2048

int
main()
{
	char bufin[MAXBUF], bufout[MAXBUF], *bi, *bo;
	fd_set rfds0, rfds1;
	int c, fdin, fdout, flags, i, nin, nout, state;
	struct timeval tv;

	if(!(fdin = open("/var/tmp/r.in", O_WRONLY)))
		err(1, "open");
	if(!(fdout = open("/var/tmp/r.out", O_RDONLY)))
		err(1, "open");

	dprintf(fdin, "export TERM=tty43 PAGER=cat EDITOR=ed\n");

	FD_ZERO(&rfds0);
	FD_ZERO(&rfds1);

	tv.tv_sec = 0;
	tv.tv_usec = 1;

	for(;;){
		/*
		 * User input is read from standard in and copied the
		 * input pipe. It is saved in bufin for later use.
		 */
		FD_SET(0, &rfds0);
		if(select(0+1, &rfds0, NULL, NULL, &tv) > 0){
			nout = read(0, bufin, MAXBUF);
			bufin[nout] = 0;
			dprintf(fdin, "%s", bufin);
			fflush(stdout);
		}

		/*
		 * System output is read from the output pipe and copied
		 * to standard out for the user to see.
		 */
		FD_SET(fdout, &rfds1);
		if(select(fdout+1, &rfds1, NULL, NULL, &tv) > 0){
			nout = read(fdout, bufout, MAXBUF);
			if(!nout) continue;
			bufout[nout] = 0;

			/*
			 * Bufin and bufout are copied to the temporary
			 * pointers bi and bo. Bo is incremented in order
			 * to skip any potential repetition of the command
			 * given by the user on standard in. (It is assumed
			 * that the typed command fits in bufin, i.e. is
			 * not larger than MAXBUF.)
			 */
			bi = bufin;
			bo = bufout;
			for(;;){
				if(*bo == '\n'){
					bo++;
					break;
				}
				if(*bo == 13){
					bo++;
					continue;
				}
				if(*bi != *bo){
					bo = bufout;
					break;
				}
				bi++; bo++;
			}

			/*
			 * Bo is printed and bufin is cleared, so as not
			 * to perform the skip again, incorrectly.
			 */
			printf("%s", bo);
			fflush(stdout);
			bufin[0] = 0;
		}
	}

}