9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: "rob pike" <rob@plan9.bell-labs.com>
To: 9fans@cse.psu.edu
Subject: [9fans] pipefile
Date: Sun, 30 Jul 2000 15:54:30 -0400	[thread overview]
Message-ID: <200007301954.PAA29225@cse.psu.edu> (raw)

I had an idea while trying to kill groundhogs today.
The command is called pipefile; it interposes a command
between you and the named file.  Options -r and -w
specify a command to interpose when reading or writing;
-b does both, but in that case the command must handle
bidirectional input; most standard commands such as
cat won't work.
Try this:

	pipefile -w 'tr a-z A-Z' /dev/cons
	rc -i < /dev/cons > /dev/cons >[2] /dev/cons

for a shell reminiscent of olden times.  The origin of the
idea was a way to support Asian input. Consider

	pipefile -r 'tr a-z A-Z' /dev/cons
	rio < /dev/cons > /dev/cons >[2] /dev/cons

I leave the rest to the interested Asian reader.

The command leaves the file in an odd state, and can only
work well on continuous files such as devices or with very
special commands interposed, but I offer it as an interesting
idea.

-rob


#include <u.h>
#include <libc.h>

#define	TEMP	"/n/temp"

void
usage(void)
{
	fprint(2, "usage: pipefile [-r command] [-w command] [-b 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:
		return;
	case 0:
		if(fd0 != 0)
			dup(fd0, 0);
		if(fd1 != 1)
			dup(fd1, 1);
		execl("/bin/rc", "rc", "-c", cmd, nil);
		sysfatal("exec %s: %r", cmd);
		break;
	}
}

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

	rcmd = wcmd = bcmd = nil;
	ARGBEGIN{
	case 'r':
		if(bcmd != nil)
			usage();
		rcmd = EARGF(usage());
		break;
	case 'w':
		if(bcmd != nil)
			usage();
		wcmd = EARGF(usage());
		break;
	case 'b':
		if(rcmd!=nil || wcmd!=nil)
			usage();
		bcmd = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

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

	file = argv[0];
	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);

	if(bcmd != nil){
		fd0 = open(TEMP "/data1", ORDWR);
		if(fd0 < 0)
			sysfatal("open %s: %r", TEMP "/data1");
		connect(bcmd, fd0, fd0);
		close(fd0);
	}else{
		fd0 = open(TEMP "/data1", OREAD);
		if(fd0 < 0)
			sysfatal("open %s: %r", TEMP "/data1");
		connect(wcmd, fd0, 1);
		fd1 = open(TEMP "/data1", OWRITE);
		if(fd1 < 0)
			sysfatal("open %s: %r", TEMP "/data1");
		connect(rcmd, 0, fd1);
		close(fd0);
		close(fd1);
	}
	unmount(nil, TEMP);
	exits(nil);
}



             reply	other threads:[~2000-07-30 19:54 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2000-07-30 19:54 rob pike [this message]
2000-07-30 22:38 Steve Harris
2000-07-30 23:06 rob pike
2000-07-30 23:17 rob pike
2000-07-30 23:46 Steve Harris
2000-07-31  1:14 rob pike
2000-08-02  3:40 ` Skip Tavakkolian
2000-08-03  1:21   ` Skip Tavakkolian
2000-07-31  4:40 okamoto
2000-07-31  4:55 rob pike
2000-07-31  9:47 okamoto
2000-08-02  7:55 okamoto
2000-08-03  8:21 ` Boyd Roberts
     [not found] <rob@plan9.bell-labs.com>
2000-08-02 14:48 ` rob pike
2000-08-02 15:49   ` James A. Robinson
2000-08-02 21:19 rob pike
2000-08-03  0:19 okamoto
2000-08-03  3:19 okamoto
2000-08-03  3:44 okamoto
2000-08-03  7:14 ` Matt
2000-08-03  4:15 okamoto
2000-08-03  4:49 rob pike
2000-08-03 23:46 okamoto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200007301954.PAA29225@cse.psu.edu \
    --to=rob@plan9.bell-labs.com \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).