1
0
mirror of synced 2026-02-26 16:23:33 +00:00
Files
1985-04-16 21:25:23 +00:00

260 lines
4.7 KiB
C

/*% cc -c -O %
*/
#include "vars.h"
char *nextip;
long count;
/*
* newfile: read a new file name (if given) from command line.
*
* nullerr: if true, error if file is null.
* savspec: decides if string[savedfile] is set.
* If savspec==SAVEIFFIRST, only save if deffile is null.
* deffile: default file name.
*
* return value: string[FILEBUF]!=deffile
* (unless SAVEIFFIRST && deffile null ==> return FALSE)
* side effects:
* can set string[savedfile]
* always sets string[FILEBUF]
* zeroes count
*/
newfile(nullerr, savspec, deffile)
char *deffile;
{
register char c;
count = 0L;
cpstr(deffile, genbuf); /* in case we strcompact() */
startstring();
c = getchar();
if(c == '\n')
copystring(genbuf);
else {
if(c != ' ')
error('f');
do c = getchar(); while(c == ' ');
while(posn(c, " \t\n") < 0){
if(c<' ' || c=='\177')
error('f');
addstring(c);
c = getchar();
}
}
setstring(FILEBUF);
if(nullerr && string[FILEBUF].str[0]=='\0')
error('f');
if(savspec==SAVEALWAYS || (savspec==SAVEIFFIRST && genbuf[0]=='\0')){
startstring();
dupstring(FILEBUF);
setstring(savedfile);
if(savspec==SAVEIFFIRST && genbuf[0]=='\0')
return(FALSE);
}
return(!eqstr(genbuf, string[FILEBUF].str));
}
exfile()
{
close(io);
io = -1;
if (vflag && initflag)
ncom('f');
else if (vflag) {
putlong(count);
putchar('\n');
}
setcount((int)count);
}
getfile()
{
register c;
register char *lp, *fp;
lp = linebuf;
fp = nextip;
do {
if (--ninbuf < 0) {
if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) {
if(ninbuf < -1)
error('r');
if(lp != linebuf)
error('N');
return(EOF);
}
fp = genbuf;
}
if (lp >= &linebuf[LBSIZE])
error('l');
if ((*lp++ = c = *fp++ ) == 0) {
lp--;
continue;
}
count++;
} while (c != '\n');
*--lp = 0;
nextip = fp;
return(0);
}
putfile()
{
int *a1;
register char *fp, *lp;
register nib;
nib = 512;
fp = genbuf;
a1 = addr1;
if(a1 == zero)
*a1++;
while(a1 <= addr2){
lp = getline(*a1++, linebuf);
for(;;){
if (--nib < 0) {
if(write(io, genbuf, fp-genbuf) < 0)
error('w');
nib = 511;
fp = genbuf;
}
count++;
if ((*fp++ = *lp++) == 0) {
fp[-1] = '\n';
break;
}
}
}
write(io, genbuf, fp-genbuf);
}
#define SIGHUP 1
#define SIGINTR 2
#define SIGQUIT 3
#define SIGBPIPE 13
int savint= -1; /* awful; this is known in error() */
Unix(type)
char type;
{
register pid, rpid;
register char *s;
int *a, c;
int getsvc();
int onbpipe;
int retcode;
char unixbuf[512];
int pipe1[2];
int pipe2[2];
int *a1, *a2, *ndot;
startstring(); /* for the \zU register */
if(type == '!')
setnoaddr();
else {
if(type == '>' || type == '|')
nonzero();
count = 0L;
if(pipe(pipe1) == -1){
lastc = '\n';
error('|');
}
}
/* Quick hack: if char is doubled, push \'zU */
if(nextchar()==type){
getchar(); /* throw it away */
pushinp(STRING, UNIX, TRUE);
}
/*
* Use c not *s as EOF and getchar() are int's
*/
for(s=unixbuf;(c=getquote("\n", getsvc))!='\n' && c!=EOF;*s++=(c&0177)){
if(s>=unixbuf+512)
error('l');
}
dropstring(); /* drop the newline */
setstring(UNIX);
*s='\0';
a1 = addr1;
a2 = addr2;
if ((pid = fork()) == 0) {
signal(SIGHUP, onhup);
signal(SIGINTR, onintr);
signal(SIGQUIT, onquit);
if(type=='<' || type=='|'){
close(1);
dup(pipe1[1]);
}else if(type == '>'){
close(0);
dup(pipe1[0]);
}
if (type != '!') {
close(pipe1[0]);
close(pipe1[1]);
}
if(type == '|'){
if(pipe(pipe2) == -1){
puts("?|");
exit(1);
}
if((pid=fork()) == 0){
close(1);
dup(pipe2[1]);
close(pipe2[0]);
close(pipe2[1]);
/*
* It's ok if we get SIGBPIPE here
*/
display('p');
exit(0);
}
if(pid == -1){
puts("Can't fork\n?!");
exit(1);
}
close(0);
dup(pipe2[0]);
close(pipe2[0]);
close(pipe2[1]);
}
execl("/bin/sh", "sh", "-c", unixbuf, 0);
exit(-1);
}
if(pid == -1){
puts("Can't fork");
error('!');
}
savint = signal(SIGINTR, 1);
if(type=='<' || type=='|') {
close(pipe1[1]);
io = pipe1[0];
ninbuf = 0;
append(getfile,addr2);
close(io);
io = -1;
ndot = dot;
} else if(type == '>') {
onbpipe = signal(SIGBPIPE, 1);
close(pipe1[0]);
a=addr1;
do{
s=getline(*a++, linebuf);
do; while(*s++);
*--s='\n';
if (write(pipe1[1],linebuf,s-(linebuf-1))<0){
puts("?o");
break;
}
}while (a<=addr2);
close(pipe1[1]);
signal(SIGBPIPE, onbpipe);
}
while ((rpid = wait(&retcode)) != pid && rpid != -1);
retcode = (retcode>>8)&0377;
settruth(retcode);
signal(SIGINTR, savint);
if(type == '|'){
if(retcode == 0){
addr1 = a1;
addr2 = a2;
delete();
dot = ndot - (a2-a1+1);
} else
error('0');
}
if(vflag)
puts("!");
}