Changeset View
Changeset View
Standalone View
Standalone View
head/bin/cp/utils.c
Show First 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
#define BUFSIZE_MAX (2*1024*1024) | #define BUFSIZE_MAX (2*1024*1024) | ||||
/* | /* | ||||
* Small (default) buffer size in bytes. It's inefficient for this to be | * Small (default) buffer size in bytes. It's inefficient for this to be | ||||
* smaller than MAXPHYS. | * smaller than MAXPHYS. | ||||
*/ | */ | ||||
#define BUFSIZE_SMALL (MAXPHYS) | #define BUFSIZE_SMALL (MAXPHYS) | ||||
static int | |||||
copy_fallback(int from_fd, int to_fd, char *buf, size_t bufsize) | |||||
{ | |||||
int rcount; | |||||
ssize_t wresid, wcount = 0; | |||||
char *bufp; | |||||
rcount = read(from_fd, buf, bufsize); | |||||
if (rcount <= 0) | |||||
return (rcount); | |||||
for (bufp = buf, wresid = rcount; ; bufp += wcount, wresid -= wcount) { | |||||
wcount = write(to_fd, bufp, wresid); | |||||
if (wcount <= 0) | |||||
break; | |||||
if (wcount >= (ssize_t)wresid) | |||||
break; | |||||
} | |||||
return (wcount < 0 ? wcount : rcount); | |||||
} | |||||
int | int | ||||
copy_file(const FTSENT *entp, int dne) | copy_file(const FTSENT *entp, int dne) | ||||
{ | { | ||||
static char *buf = NULL; | static char *buf = NULL; | ||||
static size_t bufsize; | static size_t bufsize; | ||||
struct stat *fs; | struct stat *fs; | ||||
ssize_t wcount; | ssize_t wcount; | ||||
size_t wresid; | size_t wresid; | ||||
off_t wtotal; | off_t wtotal; | ||||
int ch, checkch, from_fd, rcount, rval, to_fd; | int ch, checkch, from_fd, rcount, rval, to_fd; | ||||
char *bufp; | char *bufp; | ||||
#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED | #ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED | ||||
char *p; | char *p; | ||||
#endif | #endif | ||||
int use_copy_file_range = 1; | |||||
from_fd = to_fd = -1; | from_fd = to_fd = -1; | ||||
if (!lflag && !sflag && | if (!lflag && !sflag && | ||||
(from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) { | (from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) { | ||||
warn("%s", entp->fts_path); | warn("%s", entp->fts_path); | ||||
return (1); | return (1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | #endif | ||||
bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); | bufsize = MIN(BUFSIZE_MAX, MAXPHYS * 8); | ||||
else | else | ||||
bufsize = BUFSIZE_SMALL; | bufsize = BUFSIZE_SMALL; | ||||
buf = malloc(bufsize); | buf = malloc(bufsize); | ||||
if (buf == NULL) | if (buf == NULL) | ||||
err(1, "Not enough memory"); | err(1, "Not enough memory"); | ||||
} | } | ||||
wtotal = 0; | wtotal = 0; | ||||
while ((rcount = copy_file_range(from_fd, NULL, | do { | ||||
to_fd, NULL, bufsize, 0)) > 0) | if (use_copy_file_range) { | ||||
{ | rcount = copy_file_range(from_fd, NULL, | ||||
to_fd, NULL, bufsize, 0); | |||||
if (rcount < 0 && errno == EINVAL) { | |||||
/* Prob a non-seekable FD */ | |||||
use_copy_file_range = 0; | |||||
} | |||||
} | |||||
if (!use_copy_file_range) { | |||||
allanjude: Is there a reason this isn't juse an else? | |||||
impUnsubmitted Not Done Inline ActionsThink first time through imp: Think first time through | |||||
rcount = copy_fallback(from_fd, to_fd, | |||||
buf, bufsize); | |||||
} | |||||
wtotal += rcount; | wtotal += rcount; | ||||
if (info) { | if (info) { | ||||
info = 0; | info = 0; | ||||
(void)fprintf(stderr, | (void)fprintf(stderr, | ||||
"%s -> %s %3d%%\n", | "%s -> %s %3d%%\n", | ||||
entp->fts_path, to.p_path, | entp->fts_path, to.p_path, | ||||
cp_pct(wtotal, fs->st_size)); | cp_pct(wtotal, fs->st_size)); | ||||
} | } | ||||
} | } while (rcount > 0); | ||||
if (rcount < 0) { | if (rcount < 0) { | ||||
warn("%s", entp->fts_path); | warn("%s", entp->fts_path); | ||||
rval = 1; | rval = 1; | ||||
} | } | ||||
} | } | ||||
} else if (lflag) { | } else if (lflag) { | ||||
if (link(entp->fts_path, to.p_path)) { | if (link(entp->fts_path, to.p_path)) { | ||||
warn("%s", to.p_path); | warn("%s", to.p_path); | ||||
▲ Show 20 Lines • Show All 316 Lines • Show Last 20 Lines |
Is there a reason this isn't juse an else?