]>
git.wh0rd.org - home.git/blob - ddnuke.c
2 * released into the public domain
3 * written by Mike Frysinger <vapier>
6 #pragma GCC diagnostic warning "-Wall"
7 #pragma GCC diagnostic warning "-Wextra"
9 #define _FILE_OFFSET_BITS 64
10 #define _LARGEFILE_SOURCE
11 #define _LARGEFILE64_SOURCE
25 #include <sys/ioctl.h>
29 #define errp(msg, args...) \
31 printf("%s: " msg ": %m\n", program_invocation_short_name, ## args); \
35 static unsigned long long mbps(struct timespec
*stime
, struct timespec
*etime
, off_t len
)
38 clock_gettime(CLOCK_MONOTONIC
, etime
);
39 dtime
= ((etime
->tv_sec
- stime
->tv_sec
) * 1000 * 1000 * 1000) +
40 (etime
->tv_nsec
- stime
->tv_nsec
);
42 return 1000 * len
/ dtime
;
45 static off_t
get_blk_size(int fd
)
48 if (ioctl(fd
, BLKGETSIZE64
, &size
))
49 errp("ioctl(BLKGETSIZE64) failed");
53 static off_t
get_size(int fd
)
58 errp("could not stat %i", fd
);
60 if (S_ISREG(st
.st_mode
))
62 else if (S_ISBLK(st
.st_mode
))
63 return get_blk_size(fd
);
66 errp("unknown type of file");
69 static void nuke(int fd
, off_t offset
, off_t max_size
, unsigned char pattern
)
71 static char mem
[1024 * 1024];
72 memset(mem
, pattern
, sizeof(mem
));
74 printf("Writing 0x%X to the output\n", pattern
);
76 unsigned long long speed
= 0;
77 struct timespec stime
, etime
, itime
;
78 clock_gettime(CLOCK_MONOTONIC
, &stime
);
81 off_t pos
= offset
, last_pos
= 0;
84 while (pos
< max_size
) {
85 /* This will round up to sizeof(mem) ... */
86 ret
= write(fd
, mem
, sizeof(mem
));
88 if (ret
!= sizeof(mem
)) {
89 printf("\nread() returned %zi (wanted %zu)\n%'llu MB/s over entire run\n",
90 ret
, sizeof(mem
), mbps(&itime
, &etime
, pos
));
94 printf("%'llu bytes %u%% (%'llu MB/s)%20s\r", (unsigned long long)pos
,
95 (unsigned)((pos
* 100) / max_size
), speed
, "");
97 if ((++fsync_pos
% 16) == 0) {
98 speed
= mbps(&stime
, &etime
, pos
- last_pos
);
108 static void usage(int status
)
111 status
? stderr
: stdout
,
112 "Usage: ddnuke [options] <dev>\n"
115 " -o <offset> Position to start writing\n"
116 " -r Write random garbage to the device\n"
121 int main(int argc
, char *argv
[])
128 setlocale(LC_NUMERIC
, "en_US");
130 while ((o
= getopt(argc
, argv
, "ho:r")) != -1) {
133 offset
= atoll(optarg
);
138 case 'h': usage(EX_OK
);
139 default: usage(EX_USAGE
);
142 if (argc
!= optind
+ 1)
146 int fd
= open(file
, O_WRONLY
|O_CLOEXEC
);
148 errp("open(%s) failed", file
);
150 off_t max_size
= get_size(fd
);
152 if (lseek(fd
, offset
, SEEK_SET
) != offset
)
153 errp("lseek(%"PRIu64
"u) failed", offset
);
155 nuke(fd
, offset
, max_size
, 0x00);
157 nuke(fd
, offset
, max_size
, 0xaa);
158 nuke(fd
, offset
, max_size
, 0x55);