Linux dd 源程序

#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;
	}
}
*/
时间: 2024-10-07 06:47:33

Linux dd 源程序的相关文章

Linux DD命令

if =输入文件(或设备名称). ibs = bytes 一次读取bytes字节,即读入缓冲区的字节数. obs = bytes 一次写入bytes字节,即写 入缓冲区的字节数. cbs = bytes 一次转换bytes字节. conv = ASCII 把EBCDIC码转换为ASCII码. conv = ibm 把ASCII码转换为alternate EBCDIC码. conv = ublock 把固定们转换成变动位 conv = lcase 把字母由大写变为小写. conv = swab 交

linux dd 命令详解

1 磁盘管理 1.1 dd 1.1.1 功能说明 读取,转换并输出数据. 1.1.2 语法 dd [bs=<字节数>][cbs=<字节数>][conv=<关键字>][count=<区块数>][ibs=<字节数>][if=<文件>][obs=<字节数>][of=<文件>][seek=<区块数>][skip=<区块数>][--help][--version] 1.1.3 补充说明 dd可从标

linux dd命令参数及用法详解---用指定大小的块拷贝一个文件(也可整盘备份)

linux dd命令参数及用法详解---用指定大小的块拷贝一个文件 日期:2010-06-14 点击:3830 来源: 未知 分享至: linux dd命令使用详解 dd 的主要选项: 指定数字的地方若以下列字符结尾乘以相应的数字: b=512, c=1, k=1024, w=2, xm=number m if=file 输入文件名,缺省为标准输入. of=file 输出文件名,缺省为标准输出. ibs=bytes 一次读入 bytes 个字节(即一个块大小为 bytes 个字节). obs=b

linux dd指令

ghost和g4l 安装操作系统,速度太慢,整个过程太冗长乏味了. 安装过程中,需要回答若干问题,系统需要安装无数个软件,创建和写入无数的文件.因为涉及到大量的文件定位和读写,速度一定是快不起来的. Windows下我们常常使用ghost系统来备份和刻录操作系统.ghost可以clone整个系统的镜像,然后在新的电脑上恢复,相当简单.用ghost系统安装操作系统比使用安装光盘安装系统要快捷多了,也不需要回答任何问题了. 那么,我们能不能用ghost来备份和恢复Linux系统呢. 答案是不行.因为

Linux dd——备份命令

Linux学习笔记之备份命令dd 功能:把指定的输入文件拷贝到指定的输出文件中,并且在拷贝过程中可以进行格式转换.可以用该命令实现DOS下的diskcopy命令的作用.先用dd命令把软盘上的数据写成硬盘的一个寄存文件,再把这个寄存文件写入第二张软盘上,完成 diskcopy的功能.需要注意的是,应该将硬盘上的寄存文件用rm命令删除掉.系统默认使用标准输入文件和标准输出文件. 语法:dd [选项] if =输入文件(或设备名称). of =输出文件(或设备名称). ibs = bytes 一次读取

linux dd命令实用详解

linux dd命令刻录启动U盘详解 dd命令做usb启动盘十分方便,只须:sudo dd if=xxx.iso of=/dev/sdb bs=1M 用以上命令前必须卸载u盘,sdb是你的u盘,bs=1M是块的大小,后面的数值大,写的速度相对块一点,但也不是无限的,我一般选2M,注意,执行命令后很块完成,但u盘还在闪,等不闪了,安全移除. 注意:你的镜像需要支持dd命令. dd命令的解释. 定义 dd是Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时

[Android]用Linux dd命令做二进制拷贝

用Linux dd命令做从文件指定其实位置的二进制拷贝 示例如下: dd if=./file1.bin of=./file2.bin skip=1013 bs=1 意思是从文件file1.bin的1013个字节开始拷贝,生成文件file2.bin 指定位置:可用skip参数来制定忽略部分 bs:块大小指定为1 Byte if: 输入文件路径 of: 输出文件路径

Linux -- dd 命令

11.2 `dd': Convert and copy a file================================== `dd' copies a file (from standard input to standard output, by default)with a changeable I/O block size, while optionally performingconversions on it.  Synopses: dd [OPERAND]...    

linux dd使用记录

dd if=/dev/sda of=/dev/sdb bs=10M Linux下显示dd命令的进度: dd if=/dev/zero of=/tmp/zero.img bs=10M count=100000 想要查看上面的dd命令的执行进度,可以使用下面几种方法: 比如:每5秒输出dd的进度 方法一: watch -n 5 pkill -USR1 ^dd$ 方法二: watch -n 5 killall -USR1 dd 方法三: while killall -USR1 dd; do sleep