summaryrefslogtreecommitdiff
path: root/sys/src/cmd/pipefile.c
blob: 3c4f4dd75e149b5a07d75e7305b173fcbd56f61e (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
91
92
93
94
95
96
#include <u.h>
#include <libc.h>

#define	TEMP	"/n/temp"

void
usage(void)
{
	fprint(2, "usage: pipefile [-d] [-r command] [-w command] file\n");
	exits("usage");
}

void
connect(char *cmd, int fd0, int fd1)
{
	switch(rfork(RFPROC|RFFDG|RFREND|RFNOWAIT)){
	case -1:
		sysfatal("fork %s: %r", cmd);
		break;
	default:
		close(fd0);
		close(fd1);
		return;
	case 0:
		dup(fd0, 0);
		dup(fd1, 1);
		close(fd0);
		close(fd1);
		execl("/bin/rc", "rc", "-c", cmd, nil);
		sysfatal("exec %s: %r", cmd);
		break;
	}
}

void
main(int argc, char *argv[])
{
	char *file;
	char *rcmd, *wcmd;
	int fd0, fd1, ifd0, ifd1, dupflag;

	rfork(RFNOTEG);
	dupflag = 0;
	rcmd = wcmd = nil;
	ARGBEGIN{
	case 'd':
		dupflag = 1;
		break;
	case 'r':
		rcmd = EARGF(usage());
		break;
	case 'w':
		wcmd = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(argc!=1 || (rcmd==nil && wcmd==nil))
		usage();
	if(rcmd == nil)
		rcmd = "/bin/cat";
	if(wcmd == nil)
		wcmd = "/bin/cat";

	file = argv[0];
	if(dupflag){
		ifd0 = open(file, ORDWR);
		if(ifd0 < 0)
			sysfatal("open %s: %r", file);
		ifd1 = dup(ifd0, -1);
	}else{
		ifd0 = open(file, OREAD);
		if(ifd0 < 0)
			sysfatal("open %s: %r", file);
		ifd1 = open(file, OWRITE);
		if(ifd1 < 0)
			sysfatal("open %s: %r", file);
	}

	if(bind("#|", TEMP, MREPL) < 0)
		sysfatal("bind pipe %s: %r", TEMP);
	if(bind(TEMP "/data", file, MREPL) < 0)
		sysfatal("bind %s %s: %r", TEMP "/data", file);

	fd0 = open(TEMP "/data1", OREAD);
	if(fd0 < 0)
		sysfatal("open %s: %r", TEMP "/data1");
	connect(wcmd, fd0, ifd1);
	fd1 = open(TEMP "/data1", OWRITE);
	if(fd1 < 0)
		sysfatal("open %s: %r", TEMP "/data1");
	connect(rcmd, ifd0, fd1);
	unmount(nil, TEMP);
	exits(nil);
}