dd fix
This commit is contained in:
parent
3636254cb5
commit
2dd48bc2e2
|
@ -4,7 +4,18 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "unused.h"
|
||||
#include "human.h"
|
||||
|
||||
size_t infull, inpart;
|
||||
size_t outfull, outpart;
|
||||
off_t tbytes;
|
||||
|
||||
void summary(void) {
|
||||
fprintf(stderr, "%zu+%zu records in\n", infull, inpart);
|
||||
fprintf(stderr, "%zu+%zu records out\n", outfull, outpart);
|
||||
|
||||
fprintf(stderr, "%s total bytes copied\n", mu_humansize(tbytes));
|
||||
}
|
||||
|
||||
int openfile(int flag, char *path, int mode) {
|
||||
if (!strcmp(path, "-")) {
|
||||
|
@ -23,9 +34,9 @@ int openfile(int flag, char *path, int mode) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
size_t strtonum(char *str) {
|
||||
off_t strtonum(char *str) {
|
||||
char *p = NULL;
|
||||
size_t res = strtoll(str, &p, 10);
|
||||
off_t res = strtoll(str, &p, 10);
|
||||
if (str != p) {
|
||||
if (!strcmp(p, "b"))
|
||||
res *= 512;
|
||||
|
@ -55,6 +66,23 @@ size_t strtonum(char *str) {
|
|||
return res;
|
||||
}
|
||||
|
||||
int copy(int fd, void *buf, off_t len, off_t max) {
|
||||
off_t n = write(fd, buf, len);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (n == max)
|
||||
outfull++;
|
||||
|
||||
else if (n == len)
|
||||
outpart++;
|
||||
|
||||
tbytes += n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *ifp = "-";
|
||||
char *ofp = "-";
|
||||
|
@ -115,13 +143,23 @@ int main(int argc, char **argv) {
|
|||
obs = bs;
|
||||
}
|
||||
|
||||
/* Make input buffer */
|
||||
char *buf = malloc(ibs);
|
||||
if (buf == NULL) {
|
||||
/* Make input ibuffer */
|
||||
char *ibuf = malloc(ibs);
|
||||
if (ibuf == NULL) {
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *obuf = ibuf;
|
||||
if (ibs != obs) {
|
||||
obuf = malloc(obs);
|
||||
if (obuf == NULL) {
|
||||
free(ibuf);
|
||||
fprintf(stderr, "dd: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open files. Input */
|
||||
ifd = openfile(0, ifp, O_RDONLY);
|
||||
if (skip) {
|
||||
|
@ -143,20 +181,34 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
/* dd */
|
||||
while (1) {
|
||||
off_t n = read(ifd, ibuf, ibs);
|
||||
if (n == 0)
|
||||
break;
|
||||
|
||||
if (fsync(ofd) < 0)
|
||||
goto CLOSE;
|
||||
if (ibs == n)
|
||||
infull++;
|
||||
|
||||
else
|
||||
inpart++;
|
||||
|
||||
if (ibs == obs)
|
||||
if (copy(ofd, ibuf, n, ibs))
|
||||
goto CLOSE;
|
||||
}
|
||||
|
||||
/* End */
|
||||
fsync(ofd);
|
||||
summary();
|
||||
|
||||
ret = 0;
|
||||
|
||||
CLOSE:
|
||||
free(buf);
|
||||
free(ibuf);
|
||||
if (ibs != obs)
|
||||
free(obuf);
|
||||
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
|
||||
/* tmp */
|
||||
UNUSED(obs);
|
||||
UNUSED(count);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue