aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/dd.c
diff options
context:
space:
mode:
authorDavid du Colombier <0intro@gmail.com>2011-08-16 16:11:39 -0400
committerRuss Cox <rsc@swtch.com>2011-08-16 16:11:39 -0400
commit11a3ce57b1bb19192acd653ccee5039159f7727e (patch)
tree48af36223ae7354f041e37a4040b27c1f5a3135c /src/cmd/dd.c
parentdcdc3af143bb85012efc42c6c91f3bc7548944eb (diff)
downloadplan9port-11a3ce57b1bb19192acd653ccee5039159f7727e.tar.gz
plan9port-11a3ce57b1bb19192acd653ccee5039159f7727e.tar.bz2
plan9port-11a3ce57b1bb19192acd653ccee5039159f7727e.zip
dd: update from Plan 9
R=rsc CC=plan9port.codebot http://codereview.appspot.com/4850052
Diffstat (limited to 'src/cmd/dd.c')
-rw-r--r--src/cmd/dd.c69
1 files changed, 41 insertions, 28 deletions
diff --git a/src/cmd/dd.c b/src/cmd/dd.c
index 15599145..ad433d8e 100644
--- a/src/cmd/dd.c
+++ b/src/cmd/dd.c
@@ -1,23 +1,28 @@
#include <u.h>
#include <libc.h>
-#define BIG 2147483647
+#define BIG ((1UL<<31)-1)
+#define VBIG ((1ULL<<63)-1)
#define LCASE (1<<0)
#define UCASE (1<<1)
#define SWAB (1<<2)
#define NERR (1<<3)
#define SYNC (1<<4)
+
int cflag;
int fflag;
+
char *string;
char *ifile;
char *ofile;
char *ibuf;
char *obuf;
+
vlong skip;
vlong oseekn;
vlong iseekn;
vlong count;
+
long files = 1;
long ibs = 512;
long obs = 512;
@@ -31,18 +36,23 @@ long nipr;
long nofr;
long nopr;
long ntrunc;
+
int dotrunc = 1;
int ibf;
int obf;
+
char *op;
int nspace;
+
uchar etoa[256];
uchar atoe[256];
uchar atoibm[256];
+int quiet;
+
void flsh(void);
int match(char *s);
-vlong number(long big);
+vlong number(vlong big);
void cnull(int cc);
void null(int c);
void ascii(int cc);
@@ -50,12 +60,12 @@ void unblock(int cc);
void ebcdic(int cc);
void ibm(int cc);
void block(int cc);
-void term(void);
+void term(char*);
void stats(void);
#define iskey(s) ((key[0] == '-') && (strcmp(key+1, s) == 0))
-void
+int
main(int argc, char *argv[])
{
void (*conv)(int);
@@ -99,20 +109,24 @@ main(int argc, char *argv[])
dotrunc = number(BIG);
continue;
}
+ if(iskey("quiet")) {
+ quiet = number(BIG);
+ continue;
+ }
if(iskey("skip")) {
- skip = number(BIG);
+ skip = number(VBIG);
continue;
}
if(iskey("seek") || iskey("oseek")) {
- oseekn = number(BIG);
+ oseekn = number(VBIG);
continue;
}
if(iskey("iseek")) {
- iseekn = number(BIG);
+ iseekn = number(VBIG);
continue;
}
if(iskey("count")) {
- count = number(BIG);
+ count = number(VBIG);
continue;
}
if(iskey("files")) {
@@ -165,6 +179,8 @@ main(int argc, char *argv[])
cflag |= SYNC;
goto cloop;
}
+ fprint(2, "dd: bad conv %s\n", argv[c]);
+ exits("arg");
}
fprint(2, "dd: bad arg: %s\n", key);
exits("arg");
@@ -243,17 +259,17 @@ loop:
perror("read");
if((cflag&NERR) == 0) {
flsh();
- term();
+ term("errors");
}
ibc = 0;
for(c=0; c<ibs; c++)
if(ibuf[c] != 0)
- ibc = c;
+ ibc = c+1;
+ seek(ibf, ibs, 1);
stats();
- }
- if(ibc == 0 && --files<=0) {
+ }else if(ibc == 0 && --files<=0) {
flsh();
- term();
+ term(nil);
}
if(ibc != ibs) {
nipr++;
@@ -290,12 +306,14 @@ flsh(void)
int c;
if(obc) {
+ /* don't perror dregs of previous errors on a short write */
+ werrstr("");
c = write(obf, obuf, obc);
if(c != obc) {
if(c > 0)
++nopr;
perror("write");
- term();
+ term("errors");
}
if(obc == obs)
nofr++;
@@ -324,10 +342,10 @@ true:
}
vlong
-number(long big)
+number(vlong big)
{
char *cs;
- vlong n;
+ uvlong n;
cs = string;
n = 0;
@@ -340,11 +358,6 @@ number(long big)
n *= 1024;
continue;
-/* case 'w':
- n *= sizeof(int);
- continue;
-*/
-
case 'b':
n *= 512;
continue;
@@ -352,11 +365,11 @@ number(long big)
/* case '*':*/
case 'x':
string = cs;
- n *= number(BIG);
+ n *= number(VBIG);
case '\0':
- if(n>=big || n<0) {
- fprint(2, "dd: argument %lld out of range\n", n);
+ if(n > big) {
+ fprint(2, "dd: argument %llud out of range\n", n);
exits("range");
}
return n;
@@ -536,17 +549,17 @@ block(int cc)
}
void
-term(void)
+term(char *status)
{
-
stats();
- exits(0);
+ exits(status);
}
void
stats(void)
{
-
+ if(quiet)
+ return;
fprint(2, "%lud+%lud records in\n", nifr, nipr);
fprint(2, "%lud+%lud records out\n", nofr, nopr);
if(ntrunc)