cp: experimental stream support
This commit is contained in:
parent
71cda09d1e
commit
1d93677070
1 changed files with 50 additions and 17 deletions
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue