Add two new operands: "rif" and "rof". They operate exactly like
"if" and "of" with the exception that the communicate with a rump kernel instead of the host kernel. For example, to write stdout to /tmp/file.txt in a rump kernel namespace: dd rof=/tmp/file.txt copy /file1 to /file2 inside a rump kernel: dd rif=/file1 rof=/file2 copy a snippet from /dev/rmd0d on the rump kernel to the host fs: dd rif=/dev/rmd0d of=save seek=1000 count=3 Eat that, usermode OS. (I'll document the operands one I have some manpage to refer to for rump client use).
This commit is contained in:
parent
9be034428c
commit
6b03da8b7e
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.12 2007/10/05 07:23:09 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.13 2010/11/22 21:04:27 pooka Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= dd
|
||||
@ -8,9 +8,11 @@ DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
|
||||
.ifdef SMALLPROG
|
||||
CPPFLAGS+= -DNO_CONV
|
||||
CPPFLAGS+= -DNO_CONV -DSMALL
|
||||
.else
|
||||
SRCS+= conv_tab.c
|
||||
DPADD+= ${LIBRUMPCLIENT}
|
||||
LDADD+= -lrumpclient
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: args.c,v 1.26 2006/01/09 10:17:05 apb Exp $ */
|
||||
/* $NetBSD: args.c,v 1.27 2010/11/22 21:04:27 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: args.c,v 1.26 2006/01/09 10:17:05 apb Exp $");
|
||||
__RCSID("$NetBSD: args.c,v 1.27 2010/11/22 21:04:27 pooka Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -55,6 +55,10 @@ __RCSID("$NetBSD: args.c,v 1.26 2006/01/09 10:17:05 apb Exp $");
|
||||
#include "dd.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifndef SMALL
|
||||
#include <rump/rumpclient.h>
|
||||
#endif
|
||||
|
||||
static int c_arg(const void *, const void *);
|
||||
#ifndef NO_CONV
|
||||
static int c_conv(const void *, const void *);
|
||||
@ -72,6 +76,11 @@ static void f_seek(char *);
|
||||
static void f_skip(char *);
|
||||
static void f_progress(char *);
|
||||
|
||||
#ifndef SMALL
|
||||
static void f_rif(char *);
|
||||
static void f_rof(char *);
|
||||
#endif
|
||||
|
||||
static const struct arg {
|
||||
const char *name;
|
||||
void (*f)(char *);
|
||||
@ -85,10 +94,14 @@ static const struct arg {
|
||||
{ "count", f_count, C_COUNT, C_COUNT },
|
||||
{ "files", f_files, C_FILES, C_FILES },
|
||||
{ "ibs", f_ibs, C_IBS, C_BS|C_IBS },
|
||||
{ "if", f_if, C_IF, C_IF },
|
||||
{ "if", f_if, C_IF, C_IF|C_RIF },
|
||||
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
|
||||
{ "of", f_of, C_OF, C_OF },
|
||||
{ "of", f_of, C_OF, C_OF|C_ROF },
|
||||
{ "progress", f_progress, 0, 0 },
|
||||
#ifndef SMALL
|
||||
{ "rif", f_rif, C_RIF|C_RUMP, C_RIF|C_IF },
|
||||
{ "rof", f_rof, C_ROF|C_RUMP, C_ROF|C_ROF },
|
||||
#endif
|
||||
{ "seek", f_seek, C_SEEK, C_SEEK },
|
||||
{ "skip", f_skip, C_SKIP, C_SKIP },
|
||||
};
|
||||
@ -185,6 +198,12 @@ jcl(char **argv)
|
||||
* if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
|
||||
* errx(1, "seek offsets cannot be larger than %d", INT_MAX);
|
||||
*/
|
||||
|
||||
#ifndef SMALL
|
||||
if (ddflags & C_RUMP)
|
||||
if (rumpclient_init() == -1)
|
||||
err(1, "rumpclient init failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@ -257,6 +276,40 @@ f_of(char *arg)
|
||||
out.name = arg;
|
||||
}
|
||||
|
||||
#ifndef SMALL
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
||||
static const struct ddfops ddfops_rump = {
|
||||
.op_open = rump_sys_open,
|
||||
.op_close = rump_sys_close,
|
||||
.op_fcntl = rump_sys_fcntl,
|
||||
.op_ioctl = rump_sys_ioctl,
|
||||
.op_fstat = rump_sys_fstat,
|
||||
.op_fsync = rump_sys_fsync,
|
||||
.op_ftruncate = rump_sys_ftruncate,
|
||||
.op_lseek = rump_sys_lseek,
|
||||
.op_read = rump_sys_read,
|
||||
.op_write = rump_sys_write,
|
||||
};
|
||||
|
||||
static void
|
||||
f_rif(char *arg)
|
||||
{
|
||||
|
||||
in.name = arg;
|
||||
in.ops = &ddfops_rump;
|
||||
}
|
||||
|
||||
static void
|
||||
f_rof(char *arg)
|
||||
{
|
||||
|
||||
out.name = arg;
|
||||
out.ops = &ddfops_rump;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
f_seek(char *arg)
|
||||
{
|
||||
|
79
bin/dd/dd.c
79
bin/dd/dd.c
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dd.c,v 1.43 2009/02/14 07:13:40 lukem Exp $ */
|
||||
/* $NetBSD: dd.c,v 1.44 2010/11/22 21:04:27 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -43,7 +43,7 @@ __COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: dd.c,v 1.43 2009/02/14 07:13:40 lukem Exp $");
|
||||
__RCSID("$NetBSD: dd.c,v 1.44 2010/11/22 21:04:27 pooka Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -70,7 +70,7 @@ __RCSID("$NetBSD: dd.c,v 1.43 2009/02/14 07:13:40 lukem Exp $");
|
||||
static void dd_close(void);
|
||||
static void dd_in(void);
|
||||
static void getfdtype(IO *);
|
||||
static int redup_clean_fd(int);
|
||||
static void redup_clean_fd(IO *);
|
||||
static void setup(void);
|
||||
|
||||
int main(int, char *[]);
|
||||
@ -87,6 +87,21 @@ uint64_t progress = 0; /* display sign of life */
|
||||
const u_char *ctab; /* conversion table */
|
||||
sigset_t infoset; /* a set blocking SIGINFO */
|
||||
|
||||
static const struct ddfops ddfops_host = {
|
||||
.op_open = open,
|
||||
.op_close = close,
|
||||
.op_fcntl = fcntl,
|
||||
.op_ioctl = ioctl,
|
||||
.op_fstat = fstat,
|
||||
.op_fsync = fsync,
|
||||
.op_ftruncate = ftruncate,
|
||||
.op_lseek = lseek,
|
||||
.op_read = read,
|
||||
.op_write = write,
|
||||
};
|
||||
|
||||
#include <rump/rumpclient.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@ -127,17 +142,21 @@ static void
|
||||
setup(void)
|
||||
{
|
||||
|
||||
if (in.ops == NULL)
|
||||
in.ops = &ddfops_host;
|
||||
if (out.ops == NULL)
|
||||
out.ops = &ddfops_host;
|
||||
if (in.name == NULL) {
|
||||
in.name = "stdin";
|
||||
in.fd = STDIN_FILENO;
|
||||
} else {
|
||||
in.fd = open(in.name, O_RDONLY, 0);
|
||||
in.fd = ddop_open(in, in.name, O_RDONLY, 0);
|
||||
if (in.fd < 0)
|
||||
err(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
/* Ensure in.fd is outside the stdio descriptor range */
|
||||
in.fd = redup_clean_fd(in.fd);
|
||||
redup_clean_fd(&in);
|
||||
}
|
||||
|
||||
getfdtype(&in);
|
||||
@ -154,14 +173,15 @@ setup(void)
|
||||
} else {
|
||||
#define OFLAGS \
|
||||
(O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
|
||||
out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
|
||||
out.fd = ddop_open(out, out.name, O_RDWR | OFLAGS, DEFFILEMODE);
|
||||
/*
|
||||
* May not have read access, so try again with write only.
|
||||
* Without read we may have a problem if output also does
|
||||
* not support seeks.
|
||||
*/
|
||||
if (out.fd < 0) {
|
||||
out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
|
||||
out.fd = ddop_open(out, out.name, O_WRONLY | OFLAGS,
|
||||
DEFFILEMODE);
|
||||
out.flags |= NOREAD;
|
||||
}
|
||||
if (out.fd < 0) {
|
||||
@ -170,7 +190,7 @@ setup(void)
|
||||
}
|
||||
|
||||
/* Ensure out.fd is outside the stdio descriptor range */
|
||||
out.fd = redup_clean_fd(out.fd);
|
||||
redup_clean_fd(&out);
|
||||
}
|
||||
|
||||
getfdtype(&out);
|
||||
@ -205,7 +225,7 @@ setup(void)
|
||||
* kinds of output files, tapes, for example.
|
||||
*/
|
||||
if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
|
||||
(void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);
|
||||
(void)ddop_ftruncate(out, out.fd, (off_t)out.offset * out.dbsz);
|
||||
|
||||
/*
|
||||
* If converting case at the same time as another conversion, build a
|
||||
@ -251,13 +271,15 @@ getfdtype(IO *io)
|
||||
struct mtget mt;
|
||||
struct stat sb;
|
||||
|
||||
if (fstat(io->fd, &sb)) {
|
||||
if (io->ops->op_fstat(io->fd, &sb)) {
|
||||
err(EXIT_FAILURE, "%s", io->name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (S_ISCHR(sb.st_mode))
|
||||
io->flags |= ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
|
||||
else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
|
||||
io->flags |= io->ops->op_ioctl(io->fd, MTIOCGET, &mt)
|
||||
? ISCHR : ISTAPE;
|
||||
else if (io->ops->op_lseek(io->fd, (off_t)0, SEEK_CUR) == -1
|
||||
&& errno == ESPIPE)
|
||||
io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
|
||||
}
|
||||
|
||||
@ -267,29 +289,29 @@ getfdtype(IO *io)
|
||||
* accidentally outputting completion or error messages into the
|
||||
* output file that were intended for the tty.
|
||||
*/
|
||||
static int
|
||||
redup_clean_fd(int fd)
|
||||
static void
|
||||
redup_clean_fd(IO *io)
|
||||
{
|
||||
int fd = io->fd;
|
||||
int newfd;
|
||||
|
||||
if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
|
||||
fd != STDERR_FILENO)
|
||||
/* File descriptor is ok, return immediately. */
|
||||
return fd;
|
||||
return;
|
||||
|
||||
/*
|
||||
* 3 is the first descriptor greater than STD*_FILENO. Any
|
||||
* free descriptor valued 3 or above is acceptable...
|
||||
*/
|
||||
newfd = fcntl(fd, F_DUPFD, 3);
|
||||
newfd = io->ops->op_fcntl(fd, F_DUPFD, 3);
|
||||
if (newfd < 0) {
|
||||
err(EXIT_FAILURE, "dupfd IO");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return newfd;
|
||||
io->ops->op_close(fd);
|
||||
io->fd = newfd;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -316,7 +338,7 @@ dd_in(void)
|
||||
(void)memset(in.dbp, 0, in.dbsz);
|
||||
}
|
||||
|
||||
n = read(in.fd, in.dbp, in.dbsz);
|
||||
n = ddop_read(in, in.fd, in.dbp, in.dbsz);
|
||||
if (n == 0) {
|
||||
in.dbrcnt = 0;
|
||||
return;
|
||||
@ -343,7 +365,7 @@ dd_in(void)
|
||||
* in sector size chunks.
|
||||
*/
|
||||
if (!(in.flags & (ISPIPE|ISTAPE)) &&
|
||||
lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
|
||||
ddop_lseek(in, in.fd, (off_t)in.dbsz, SEEK_CUR))
|
||||
warn("%s", in.name);
|
||||
|
||||
/* If sync not specified, omit block and continue. */
|
||||
@ -431,11 +453,12 @@ dd_close(void)
|
||||
* 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) {
|
||||
if (out.fd == STDOUT_FILENO && ddop_fsync(out, out.fd) == -1
|
||||
&& errno != EINVAL) {
|
||||
err(EXIT_FAILURE, "fsync stdout");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (close(out.fd) == -1) {
|
||||
if (ddop_close(out, out.fd) == -1) {
|
||||
err(EXIT_FAILURE, "close");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -484,12 +507,12 @@ dd_out(int force)
|
||||
}
|
||||
}
|
||||
if (pending != 0) {
|
||||
if (lseek(out.fd, pending, SEEK_CUR) ==
|
||||
-1)
|
||||
if (ddop_lseek(out,
|
||||
out.fd, pending, SEEK_CUR) == -1)
|
||||
err(EXIT_FAILURE, "%s: seek error creating sparse file",
|
||||
out.name);
|
||||
}
|
||||
nw = bwrite(out.fd, outp, cnt);
|
||||
nw = bwrite(&out, outp, cnt);
|
||||
if (nw <= 0) {
|
||||
if (nw == 0)
|
||||
errx(EXIT_FAILURE,
|
||||
@ -545,14 +568,14 @@ dd_out(int force)
|
||||
* A protected against SIGINFO write
|
||||
*/
|
||||
ssize_t
|
||||
bwrite(int fd, const void *buf, size_t len)
|
||||
bwrite(IO *io, 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);
|
||||
rv = io->ops->op_write(io->fd, buf, len);
|
||||
oerrno = errno;
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
errno = oerrno;
|
||||
|
35
bin/dd/dd.h
35
bin/dd/dd.h
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dd.h,v 1.12 2004/01/17 20:48:57 dbj Exp $ */
|
||||
/* $NetBSD: dd.h,v 1.13 2010/11/22 21:04:27 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -35,6 +35,35 @@
|
||||
* @(#)dd.h 8.3 (Berkeley) 4/2/94
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct ddfops {
|
||||
int (*op_open)(const char *, int, ...);
|
||||
int (*op_close)(int);
|
||||
|
||||
int (*op_fcntl)(int, int, ...);
|
||||
int (*op_ioctl)(int, unsigned long, ...);
|
||||
|
||||
int (*op_fstat)(int, struct stat *);
|
||||
int (*op_fsync)(int);
|
||||
int (*op_ftruncate)(int, off_t);
|
||||
|
||||
off_t (*op_lseek)(int, off_t, int);
|
||||
|
||||
ssize_t (*op_read)(int, void *, size_t);
|
||||
ssize_t (*op_write)(int, const void *, size_t);
|
||||
};
|
||||
|
||||
#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, __VA_ARGS__)
|
||||
#define ddop_close(dir, a1) dir.ops->op_close(a1)
|
||||
#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, __VA_ARGS__)
|
||||
#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, __VA_ARGS__)
|
||||
#define ddop_fsync(dir, a1) dir.ops->op_fsync(a1)
|
||||
#define ddop_ftruncate(dir, a1, a2) dir.ops->op_ftruncate(a1, 2)
|
||||
#define ddop_lseek(dir, a1, a2, a3) dir.ops->op_lseek(a1, a2, a3)
|
||||
#define ddop_read(dir, a1, a2, a3) dir.ops->op_read(a1, a2, a3)
|
||||
#define ddop_write(dir, a1, a2, a3) dir.ops->op_write(a1, a2, a3)
|
||||
|
||||
/* Input/output stream state. */
|
||||
typedef struct {
|
||||
u_char *db; /* buffer address */
|
||||
@ -52,6 +81,7 @@ typedef struct {
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
uint64_t offset; /* # of blocks to skip */
|
||||
struct ddfops const *ops; /* ops to use with fd */
|
||||
} IO;
|
||||
|
||||
typedef struct {
|
||||
@ -89,3 +119,6 @@ typedef struct {
|
||||
#define C_UNBLOCK 0x80000
|
||||
#define C_OSYNC 0x100000
|
||||
#define C_SPARSE 0x200000
|
||||
#define C_RIF 0x400000
|
||||
#define C_ROF 0x800000
|
||||
#define C_RUMP 0x1000000
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: extern.h,v 1.17 2006/01/09 10:17:05 apb Exp $ */
|
||||
/* $NetBSD: extern.h,v 1.18 2010/11/22 21:04:28 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -50,7 +50,7 @@ void summaryx(int);
|
||||
void terminate(int);
|
||||
void unblock(void);
|
||||
void unblock_close(void);
|
||||
ssize_t bwrite(int, const void *, size_t);
|
||||
ssize_t bwrite(IO *, const void *, size_t);
|
||||
|
||||
extern IO in, out;
|
||||
extern STAT st;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: position.c,v 1.17 2009/02/14 07:13:40 lukem Exp $ */
|
||||
/* $NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993, 1994
|
||||
@ -38,7 +38,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: position.c,v 1.17 2009/02/14 07:13:40 lukem Exp $");
|
||||
__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -70,7 +70,7 @@ pos_in(void)
|
||||
|
||||
/* If not a pipe or tape device, try to seek on it. */
|
||||
if (!(in.flags & (ISPIPE|ISTAPE))) {
|
||||
if (lseek(in.fd,
|
||||
if (ddop_lseek(in, in.fd,
|
||||
(off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
|
||||
err(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
@ -85,7 +85,7 @@ pos_in(void)
|
||||
* blocks for other devices.
|
||||
*/
|
||||
for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
|
||||
if ((nr = read(in.fd, in.db, bcnt)) > 0) {
|
||||
if ((nr = ddop_read(in, in.fd, in.db, bcnt)) > 0) {
|
||||
if (in.flags & ISPIPE) {
|
||||
if (!(bcnt -= nr)) {
|
||||
bcnt = in.dbsz;
|
||||
@ -137,7 +137,7 @@ pos_out(void)
|
||||
* have specified the seek operand.
|
||||
*/
|
||||
if (!(out.flags & ISTAPE)) {
|
||||
if (lseek(out.fd,
|
||||
if (ddop_lseek(out, out.fd,
|
||||
(off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
@ -149,7 +149,7 @@ pos_out(void)
|
||||
t_op.mt_op = MTFSR;
|
||||
t_op.mt_count = out.offset;
|
||||
|
||||
if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)
|
||||
if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) < 0)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
@ -157,7 +157,7 @@ pos_out(void)
|
||||
|
||||
/* Read it. */
|
||||
for (cnt = 0; cnt < out.offset; ++cnt) {
|
||||
if ((n = read(out.fd, out.db, out.dbsz)) > 0)
|
||||
if ((n = ddop_read(out, out.fd, out.db, out.dbsz)) > 0)
|
||||
continue;
|
||||
|
||||
if (n < 0)
|
||||
@ -171,12 +171,13 @@ pos_out(void)
|
||||
*/
|
||||
t_op.mt_op = MTBSR;
|
||||
t_op.mt_count = 1;
|
||||
if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
|
||||
if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) == -1)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
while (cnt++ < out.offset)
|
||||
if ((uint64_t)(n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz)
|
||||
if ((uint64_t)(n = bwrite(&out,
|
||||
out.db, out.dbsz)) != out.dbsz)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user