#include "a.h"
/*
* 19. Input/output file switching.
*/
/* .so - push new source file */
void
r_so(int argc, Rune **argv)
{
USED(argc);
pushinputfile(argv[1]);
}
/* .nx - end this file, switch to arg */
void
r_nx(int argc, Rune **argv)
{
int n;
if(argc == 1){
while(popinput())
;
}else{
if(argc > 2)
warn("too many arguments for .nx");
while((n=popinput()) && n != 2)
;
pushinputfile(argv[1]);
}
}
/* .sy - system: run string */
void
r_sy(Rune *name)
{
USED(name);
warn(".sy not implemented");
}
/* .pi - pipe output to string */
void
r_pi(Rune *name)
{
USED(name);
warn(".pi not implemented");
}
/* .cf - copy contents of filename to output */
void
r_cf(int argc, Rune **argv)
{
int c;
char *p;
Biobuf *b;
USED(argc);
p = esmprint("%S", argv[1]);
if((b = Bopen(p, OREAD)) == nil){
fprint(2, "%L: open %s: %r\n", p);
free(p);
return;
}
free(p);
while((c = Bgetrune(b)) >= 0)
outrune(c);
Bterm(b);
}
void
r_inputpipe(Rune *name)
{
Rune *cmd, *stop, *line;
int n, pid, p[2], len;
Waitmsg *w;
USED(name);
if(pipe(p) < 0){
warn("pipe: %r");
return;
}
stop = copyarg();
cmd = readline(CopyMode);
pid = fork();
switch(pid){
case 0:
if(p[0] != 0){
dup(p[0], 0);
close(p[0]);
}
close(p[1]);
execl("/bin/rc", "rc", "-c", esmprint("%S", cmd), nil);
warn("%Cdp %S: %r", dot, cmd);
_exits(nil);
case -1:
warn("fork: %r");
default:
close(p[0]);
len = runestrlen(stop);
fprint(p[1], ".ps %d\n", getnr(L(".s")));
fprint(p[1], ".vs %du\n", getnr(L(".v")));
fprint(p[1], ".ft %d\n", getnr(L(".f")));
fprint(p[1], ".ll 8i\n");
fprint(p[1], ".pl 30i\n");
while((line = readline(~0)) != nil){
if(runestrncmp(line, stop, len) == 0
&& (line[len]==' ' || line[len]==0 || line[len]=='\t'
|| (line[len]=='\\' && line[len+1]=='}')))
break;
n = runestrlen(line);
line[n] = '\n';
fprint(p[1], "%.*S", n+1, line);
free(line);
}
free(stop);
close(p[1]);
w = wait();
if(w == nil){
warn("wait: %r");
return;
}
if(w->msg[0])
sysfatal("%C%S %S: %s", dot, name, cmd, w->msg);
free(cmd);
free(w);
}
}
void
t19init(void)
{
addreq(L("so"), r_so, 1);
addreq(L("nx"), r_nx, -1);
addraw(L("sy"), r_sy);
addraw(L("inputpipe"), r_inputpipe);
addraw(L("pi"), r_pi);
addreq(L("cf"), r_cf, 1);
nr(L("$$"), getpid());
}
|