⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dd.c

📁 Android 一些工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);		out.dbcnt = out.dbsz;	}	/* If there are pending sparse blocks, make sure	 * to write out the final block un-sparse	 */	if ((out.dbcnt == 0) && pending) {		memset(out.db, 0, out.dbsz);		out.dbcnt = out.dbsz;		out.dbp = out.db + out.dbcnt;		pending -= out.dbsz;	}	if (out.dbcnt)		dd_out(1);	/*	 * Reporting nfs write error may be defered until next	 * write(2) or close(2) system call.  So, we need to do an	 * extra check.  If an output is stdout, the file structure	 * may be shared among with other processes and close(2) just	 * decreases the reference count.	 */	if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) {		fprintf(stderr, "fsync stdout: %s\n", strerror(errno));		exit(1);		/* NOTREACHED */	}	if (close(out.fd) == -1) {		fprintf(stderr, "close: %s\n", strerror(errno));		exit(1);		/* NOTREACHED */	}}voiddd_out(int force){	static int warned;	int64_t cnt, n, nw;	u_char *outp;	/*	 * Write one or more blocks out.  The common case is writing a full	 * output block in a single write; increment the full block stats.	 * Otherwise, we're into partial block writes.  If a partial write,	 * and it's a character device, just warn.  If a tape device, quit.	 *	 * The partial writes represent two cases.  1: Where the input block	 * was less than expected so the output block was less than expected.	 * 2: Where the input block was the right size but we were forced to	 * write the block in multiple chunks.  The original versions of dd(1)	 * never wrote a block in more than a single write, so the latter case	 * never happened.	 *	 * One special case is if we're forced to do the write -- in that case	 * we play games with the buffer size, and it's usually a partial write.	 */	outp = out.db;	for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {		for (cnt = n;; cnt -= nw) {			if (!force && ddflags & C_SPARSE) {				int sparse, i;				sparse = 1;	/* Is buffer sparse? */				for (i = 0; i < cnt; i++)					if (outp[i] != 0) {						sparse = 0;						break;					}				if (sparse) {					pending += cnt;					outp += cnt;					nw = 0;					break;				}			}			if (pending != 0) {				if (lseek(out.fd, pending, SEEK_CUR) ==				    -1) {					fprintf(stderr,						"%s: seek error creating "						"sparse file: %s\n",						out.name, strerror(errno));					exit(1);				}			}			nw = bwrite(out.fd, outp, cnt);			if (nw <= 0) {				if (nw == 0) {					fprintf(stderr, "%s: end of device\n",						out.name);					exit(1);					/* NOTREACHED */				}				if (errno != EINTR) {					fprintf(stderr, "%s: write error: %s\n",						out.name, strerror(errno));					/* NOTREACHED */					exit(1);				}				nw = 0;			}			if (pending) {				st.bytes += pending;				st.sparse += pending/out.dbsz;				st.out_full += pending/out.dbsz;				pending = 0;			}			outp += nw;			st.bytes += nw;			if (nw == n) {				if (n != out.dbsz)					++st.out_part;				else					++st.out_full;				break;			}			++st.out_part;			if (nw == cnt)				break;			if (out.flags & ISCHR && !warned) {				warned = 1;				fprintf(stderr, "%s: short write on character "					"device\n", out.name);			}			if (out.flags & ISTAPE) {				fprintf(stderr,					"%s: short write on tape device",					out.name);				exit(1);				/* NOTREACHED */			}		}		if ((out.dbcnt -= n) < out.dbsz)			break;	}	/* Reassemble the output block. */	if (out.dbcnt)		(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);	out.dbp = out.db + out.dbcnt;	if (progress)		(void)write(STDERR_FILENO, ".", 1);}/* * A protected against SIGINFO write */ssize_tbwrite(int fd, const void *buf, size_t len){	sigset_t oset;	ssize_t rv;	int oerrno;	(void)sigprocmask(SIG_BLOCK, &infoset, &oset);	rv = write(fd, buf, len);	oerrno = errno;	(void)sigprocmask(SIG_SETMASK, &oset, NULL);	errno = oerrno;	return (rv);}/* * Position input/output data streams before starting the copy.  Device type * dependent.  Seekable devices use lseek, and the rest position by reading. * Seeking past the end of file can cause null blocks to be written to the * output. */voidpos_in(void){	int bcnt, cnt, nr, warned;	/* If not a pipe or tape device, try to seek on it. */	if (!(in.flags & (ISPIPE|ISTAPE))) {		if (lseek(in.fd,		    (off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {			fprintf(stderr, "%s: seek error: %s",				in.name, strerror(errno));			exit(1);			/* NOTREACHED */		}		return;		/* NOTREACHED */	}	/*	 * Read the data.  If a pipe, read until satisfy the number of bytes	 * being skipped.  No differentiation for reading complete and partial	 * blocks for other devices.	 */	for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {		if ((nr = read(in.fd, in.db, bcnt)) > 0) {			if (in.flags & ISPIPE) {				if (!(bcnt -= nr)) {					bcnt = in.dbsz;					--cnt;				}			} else				--cnt;			continue;		}		if (nr == 0) {			if (files_cnt > 1) {				--files_cnt;				continue;			}			fprintf(stderr, "skip reached end of input\n");			exit(1);			/* NOTREACHED */		}		/*		 * Input error -- either EOF with no more files, or I/O error.		 * If noerror not set die.  POSIX requires that the warning		 * message be followed by an I/O display.		 */		if (ddflags & C_NOERROR) {			if (!warned) {				fprintf(stderr, "%s: error occurred\n",					in.name);				warned = 1;				summary();			}			continue;		}		fprintf(stderr, "%s: read error: %s", in.name, strerror(errno));		exit(1);		/* NOTREACHED */	}}voidpos_out(void){//	struct mtop t_op;	int cnt, n;	/*	 * If not a tape, try seeking on the file.  Seeking on a pipe is	 * going to fail, but don't protect the user -- they shouldn't	 * have specified the seek operand.	 */	if (!(out.flags & ISTAPE)) {		if (lseek(out.fd,		    (off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1) {			fprintf(stderr, "%s: seek error: %s\n",				out.name, strerror(errno));			exit(1);			/* NOTREACHED */		}		return;	}	/* If no read access, try using mtio. */	if (out.flags & NOREAD) {/*		t_op.mt_op = MTFSR;		t_op.mt_count = out.offset;		if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)*/			fprintf(stderr, "%s: cannot read", out.name);			exit(1);			/* NOTREACHED */		return;	}	/* Read it. */	for (cnt = 0; cnt < out.offset; ++cnt) {		if ((n = read(out.fd, out.db, out.dbsz)) > 0)			continue;		if (n < 0) {			fprintf(stderr, "%s: cannot position by reading: %s\n",				out.name, strerror(errno));			exit(1);			/* NOTREACHED */		}		/*		 * If reach EOF, fill with NUL characters; first, back up over		 * the EOF mark.  Note, cnt has not yet been incremented, so		 * the EOF read does not count as a seek'd block.		 *//*		t_op.mt_op = MTBSR;		t_op.mt_count = 1;		if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) */ {			fprintf(stderr, "%s: cannot position\n", out.name);			exit(1);			/* NOTREACHED */		}		while (cnt++ < out.offset)			if ((n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz) {				fprintf(stderr, "%s: cannot position "					"by writing: %s\n",					out.name, strerror(errno));				exit(1);				/* NOTREACHED */			}		break;	}}/* * def -- * Copy input to output.  Input is buffered until reaches obs, and then * output until less than obs remains.  Only a single buffer is used. * Worst case buffer calculation is (ibs + obs - 1). */voiddef(void){	uint64_t cnt;	u_char *inp;	const u_char *t;	if ((t = ctab) != NULL)		for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)			*inp = t[*inp];	/* Make the output buffer look right. */	out.dbp = in.dbp;	out.dbcnt = in.dbcnt;	if (in.dbcnt >= out.dbsz) {		/* If the output buffer is full, write it. */		dd_out(0);		/*		 * Ddout copies the leftover output to the beginning of		 * the buffer and resets the output buffer.  Reset the		 * input buffer to match it.	 	 */		in.dbp = out.dbp;		in.dbcnt = out.dbcnt;	}}voiddef_close(void){	/* Just update the count, everything is already in the buffer. */	if (in.dbcnt)		out.dbcnt = in.dbcnt;}#ifdef	NO_CONV/* Build a smaller version (i.e. for a miniroot) *//* These can not be called, but just in case...  */static const char no_block[] = "unblock and -DNO_CONV?\n";void block(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }void block_close(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }void unblock(void)		{ fprintf(stderr, "%s", no_block); exit(1); }void unblock_close(void)	{ fprintf(stderr, "%s", no_block); exit(1); }#else	/* NO_CONV *//* * Copy variable length newline terminated records with a max size cbsz * bytes to output.  Records less than cbs are padded with spaces. * * max in buffer:  MAX(ibs, cbsz) * max out buffer: obs + cbsz */voidblock(void){	static int intrunc;	int ch = 0;	/* pacify gcc */	uint64_t cnt, maxlen;	u_char *inp, *outp;	const u_char *t;	/*	 * Record truncation can cross block boundaries.  If currently in a	 * truncation state, keep tossing characters until reach a newline.	 * Start at the beginning of the buffer, as the input buffer is always	 * left empty.	 */	if (intrunc) {		for (inp = in.db, cnt = in.dbrcnt;		    cnt && *inp++ != '\n'; --cnt);		if (!cnt) {			in.dbcnt = 0;			in.dbp = in.db;			return;		}		intrunc = 0;		/* Adjust the input buffer numbers. */		in.dbcnt = cnt - 1;		in.dbp = inp + cnt - 1;	}	/*	 * Copy records (max cbsz size chunks) into the output buffer.  The	 * translation is done as we copy into the output buffer.	 */	for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {		maxlen = MIN(cbsz, in.dbcnt);		if ((t = ctab) != NULL)			for (cnt = 0;			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)				*outp++ = t[ch];		else			for (cnt = 0;			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)				*outp++ = ch;		/*		 * Check for short record without a newline.  Reassemble the		 * input block.		 */		if (ch != '\n' && in.dbcnt < cbsz) {			(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);			break;		}		/* Adjust the input buffer numbers. */		in.dbcnt -= cnt;		if (ch == '\n')			--in.dbcnt;		/* Pad short records with spaces. */		if (cnt < cbsz)			(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);		else {			/*			 * If the next character wouldn't have ended the			 * block, it's a truncation.			 */			if (!in.dbcnt || *inp != '\n')				++st.trunc;			/* Toss characters to a newline. */			for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);			if (!in.dbcnt)				intrunc = 1;			else				--in.dbcnt;		}		/* Adjust output buffer numbers. */		out.dbp += cbsz;		if ((out.dbcnt += cbsz) >= out.dbsz)			dd_out(0);		outp = out.dbp;	}	in.dbp = in.db + in.dbcnt;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -