#include "stdio.h" #include "stdlib.h" #include "sys/stat.h" #include "sys/types.h" #include "fcntl.h" #define BLOCK_SIZE 512 #define BUF_SIZE 1024 #define TOTAL_BUF (BUF_SIZE<<1) typedef struct { char data[BUF_SIZE*2+1]; int base,top; int length; }buf_queue; void do_dd(int infilefd ,int outfilefd ,int iperbytes ,int operbytes ,int cperbytes ,int totalblocks); static inline int buf_empty(buf_queue *buf); static inline int buf_length(buf_queue *buf); int read2buf(int fd,buf_queue *buf,int size); int writefrombuf(int fd,buf_queue *buf,int size); int main(int argc,char **argv) { int i; int iperbytes=BLOCK_SIZE,operbytes=BLOCK_SIZE,cperbytes=0; int totalblocks = -1,seekblocks=0,skipblocks=0; clock_t begin,end; off_t fbegin,fend; int noxfer=0; int infilefd,outfilefd; char *infile=NULL,*outfile=NULL,*iflags=NULL,*oflags=NULL; for(i=1;i<argc ;i++) { if(!strncmp(argv[i],"bs",strlen("bs"))) { iperbytes = operbytes = atoi(argv[i]+strlen("bs")+1); }else if (!strncmp(argv[i],"cbs",strlen("cbs"))) { cperbytes = atoi(argv[i]+strlen("cbs")+1); }else if (!strncmp(argv[i],"conv")) { }else if (!strncmp(argv[i],"count",strlen("count"))) { totalblocks = atoi(argv[i]+strlen("count")+1); }else if (!strncmp(argv[i],"ibs",strlen("ibs"))) { iperbytes = atoi(argv[i]+strlen("ibs")+1); }else if (!strncmp(argv[i],"obs",strlen("obs"))) { operbytes = atoi(argv[i]+strlen("obs")+1); }else if (!strncmp(argv[i],"if",strlen("if"))) { infile = argv[i]+strlen("if")+1; }else if (!strncmp(argv[i],"of",strlen("of"))) { outfile = argv[i]+strlen("of")+1; }else if (!strncmp(argv[i],"iflag",strlen("iflag"))) { iflags = argv[i]+strlen("iflag")+1; }else if (!strncmp(argv[i],"oflag",strlen("oflag"))) { oflags = argv[i]+strlen("oflag")+1; } else if (!strncmp(argv[i],"seek",strlen("seek"))) { seekblocks = atoi(argv[i] + strlen("seek")+1); }else if (!strncmp(argv[i],"skip",strlen("skip"))) { skipblocks = atoi(argv[i] + strlen("skip")+1); }else if (!strncmp(argv[i],"status",strlen("status"))) { noxfer =!strncmp(argv[i]+strlen("status")+1,"noxfer",strlen("noxfer")); } } if(infile) { if((infilefd = open(infile,O_RDONLY))== -1) { perror("open infile error : "); return -1; } }else { infilefd = fileno(stdin); } lseek(infilefd,skipblocks*BLOCK_SIZE,SEEK_SET); if(outfile) { if(seekblocks!=0) { outfilefd = open(outfile, O_APPEND | O_WRONLY); }else { outfilefd = open(outfile, O_CREAT|O_WRONLY|O_TRUNC,00660); } if(outfilefd == -1) { perror("open outfile error : "); close(infilefd); return -1; } } else { outfilefd = fileno(stdout); } lseek(outfilefd,seekblocks*BLOCK_SIZE,SEEK_SET); do_dd(infilefd,outfilefd,iperbytes,operbytes,cperbytes,totalblocks); } void do_dd(int infilefd ,int outfilefd ,int iperbytes ,int operbytes ,int cperbytes ,int totalblocks) { buf_queue *buf; int readbytes = 0,writebytes =0; if( (iperbytes > (BUF_SIZE*2)) && (operbytes > (BUF_SIZE * 2))) iperbytes = operbytes = BUF_SIZE*2; else { if(iperbytes > BUF_SIZE) iperbytes = BUF_SIZE; if(operbytes > BUF_SIZE) operbytes = BUF_SIZE; } if((buf = (buf_queue* )malloc(sizeof(buf_queue)))==NULL) perror("malloc memory failed :"); buf->base=buf->top=0; buf->length =0; readbytes = iperbytes; writebytes = operbytes; while(readbytes == iperbytes ) { while((buf_empty(buf) >= iperbytes) && (readbytes == iperbytes) ) { readbytes = read2buf(infilefd,buf,iperbytes); } while( buf_length(buf) >= operbytes && (writebytes == operbytes)) { writefrombuf(outfilefd,buf,operbytes); } } writefrombuf(outfilefd,buf,buf_length(buf)); } inline int buf_empty(buf_queue *buf) { return TOTAL_BUF-buf->length; } inline int buf_length(buf_queue *buf) { return buf->length; } //read data into top and need the stuation is size < buf_empty; int read2buf(int fd,buf_queue *buf,int size) { int readbytes,totalread = 0,toread; if(size > (TOTAL_BUF-buf->top)) toread = TOTAL_BUF - buf->top; else toread = size; while(toread) { if((readbytes = read(fd,buf->data+buf->top,toread)) == -1) { perror("read file error : "); return -1; } totalread += readbytes; buf->length +=readbytes; buf->top = (buf->top + readbytes) % TOTAL_BUF; if(readbytes != toread) return totalread; toread = size - toread; size = toread; } return totalread; } //read data into top and need the stuation is size < buf_empty; int writefrombuf(int fd,buf_queue *buf,int size) { int writebytes,totalwrite = 0,towrite; if(size > (TOTAL_BUF-buf->base)) towrite = TOTAL_BUF - buf->base; else towrite = size; while(towrite) { if((writebytes = write(fd,buf->data+buf->base,towrite)) == -1) { perror("write error "); return -1; } totalwrite += writebytes; buf->length-=writebytes; buf->base = (buf->base + writebytes) % TOTAL_BUF; if(writebytes != towrite) return totalwrite; towrite = size - towrite; size = towrite; } return totalwrite; } /* //read data into top and need the stuation is size < buf_empty; int read2buf(int fd,char *buf,char *base,char *top,int size) { int toread = 0,readbytes = 0; if(top > base) { toread = buf + BUF_SIZE - top if(size <= toread) { toread = size; readbytes = read(fd,top,toread); top = top + ((top - buf + readbytes) % BUF_SIZE) return readbytes; }else { readbytes = read(fd,top,toread); top = top + ((top - buf + readbytes) % BUF_SIZE) if(readbytes != toread) return readbytes; else { toread = size-toread; readbytes = read(fd,top,toread); top = top + ((top - buf + readbytes) % BUF_SIZE) return size-(toread - size) } } } else { readbytes = read(fd,top,size); top = top + ((top - buf + readbytes) % BUF_SIZE) return readbytes; } } */
原文地址:http://990487026.blog.51cto.com/10133282/1937255