dd: update from Plan 9

R=rsc
CC=plan9port.codebot
http://codereview.appspot.com/4850052
This commit is contained in:
David du Colombier 2011-08-16 16:11:39 -04:00 committed by Russ Cox
parent dcdc3af143
commit 11a3ce57b1
2 changed files with 239 additions and 28 deletions

View file

@ -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)