cp: experimental stream support

This commit is contained in:
cinap_lenrek 2015-07-19 03:32:09 +02:00
parent 71cda09d1e
commit 1d93677070

View file

@ -3,6 +3,7 @@
#define DEFB (8*1024) #define DEFB (8*1024)
int buflen;
int failed; int failed;
int gflag; int gflag;
int uflag; int uflag;
@ -79,7 +80,7 @@ copy(char *from, char *to, int todir)
{ {
Dir *dirb, dirt; Dir *dirb, dirt;
char *name; char *name;
int fdf, fdt, mode; int fdf, fdt, fds, mode;
name = nil; name = nil;
if(todir){ if(todir){
@ -92,7 +93,7 @@ copy(char *from, char *to, int todir)
to = name; to = name;
} }
fdf = fdt = -1; fdf = fdt = fds = -1;
if((dirb=dirstat(from))==nil){ if((dirb=dirstat(from))==nil){
fprint(2,"cp: can't stat %s: %r\n", from); fprint(2,"cp: can't stat %s: %r\n", from);
failed = 1; failed = 1;
@ -121,25 +122,52 @@ copy(char *from, char *to, int todir)
failed = 1; failed = 1;
goto out; goto out;
} }
if(copy1(fdf, fdt, from, to)==0 && (xflag || gflag || uflag)){
nulldir(&dirt); buflen = iounit(fdf);
if(xflag){ if(buflen <= 0)
dirt.mtime = dirb->mtime; buflen = DEFB;
dirt.mode = dirb->mode;
if(dirb->length/2 > buflen){
char nam[32];
snprint(nam, sizeof nam, "/fd/%dstream", fdf);
fds = open(nam, OREAD);
if(fds >= 0){
close(fdf);
fdf = fds;
} }
if(uflag) snprint(nam, sizeof nam, "/fd/%dstream", fdt);
dirt.uid = dirb->uid; fds = open(nam, OWRITE);
if(gflag) }
dirt.gid = dirb->gid;
if(dirfwstat(fdt, &dirt) < 0) if(copy1(fdf, fds < 0 ? fdt : fds, from, to)==0){
fprint(2, "cp: warning: can't wstat %s: %r\n", to); if(fds >= 0 && write(fds, "", 0) < 0){
} fprint(2, "cp: error writing %s: %r\n", to);
failed = 1;
goto out;
}
if(xflag || gflag || uflag){
nulldir(&dirt);
if(xflag){
dirt.mtime = dirb->mtime;
dirt.mode = dirb->mode;
}
if(uflag)
dirt.uid = dirb->uid;
if(gflag)
dirt.gid = dirb->gid;
if(dirfwstat(fdt, &dirt) < 0)
fprint(2, "cp: warning: can't wstat %s: %r\n", to);
}
}
out: out:
free(dirb);
if(fdf >= 0) if(fdf >= 0)
close(fdf); close(fdf);
if(fdt >= 0) if(fdt >= 0)
close(fdt); close(fdt);
if(fds >= 0)
close(fds);
free(dirb);
free(name); free(name);
} }
@ -151,13 +179,18 @@ copy1(int fdf, int fdt, char *from, char *to)
int rv; int rv;
char err[ERRMAX]; char err[ERRMAX];
buf = malloc(DEFB); buf = malloc(buflen);
if(buf == nil){
fprint(2, "cp: out of memory\n");
return -1;
}
/* clear any residual error */ /* clear any residual error */
err[0] = '\0'; err[0] = '\0';
errstr(err, ERRMAX); errstr(err, ERRMAX);
rv = 0; rv = 0;
for(rcount=0;; rcount++) { for(rcount=0;; rcount++) {
n = read(fdf, buf, DEFB); n = read(fdf, buf, buflen);
if(n <= 0) if(n <= 0)
break; break;
n1 = write(fdt, buf, n); n1 = write(fdt, buf, n);