static int w_flag = 0; /* do r/w test: 0=no, 1=yes,
* 2=non-destructive */
static int s_flag = 0; /* show progress of test */
+static int force = 0; /* force check of mounted device */
-static char *blkbuf; /* Allocation array for bad block testing */
-
-
-static void usage(void)
+static void usage(NOARGS)
{
- fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwn]\n [-c blocks_at_once] [-p num_passes] device [blocks_count] [start_count]\n"),
+ fprintf(stderr, _("Usage: %s [-b block_size] [-i input_file] [-o output_file] [-svwnf]\n [-c blocks_at_once] [-p num_passes] device [blocks_count [start_count]]\n"),
program_name);
exit (1);
}
static blk_t next_bad = 0;
static ext2_badblocks_iterate bb_iter = NULL;
+/* Everything is STDC, these days */
+#define NOARGS void
+
/*
* This routine reports a new bad block. If the bad block has already
* been seen before, then it returns 0; otherwise it returns 1.
return 1;
}
-static void print_status (void)
+static void print_status(NOARGS)
{
fprintf(stderr, "%9ld/%9ld", currently_testing, num_blocks);
fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
fflush (stderr);
}
-static void alarm_intr (int alnum)
+static void alarm_intr(int alnum)
{
signal (SIGALRM, alarm_intr);
alarm(1);
static void *terminate_addr = NULL;
-static void terminate_intr (int signo)
+static void terminate_intr(int signo)
{
if (terminate_addr)
longjmp(terminate_addr,1);
exit(1);
}
-static void capture_terminate (jmp_buf term_addr)
+static void capture_terminate(jmp_buf term_addr)
{
terminate_addr = term_addr;
signal (SIGHUP, terminate_intr);
signal (SIGUSR2, terminate_intr);
}
-static void uncapture_terminate()
+static void uncapture_terminate(NOARGS)
{
terminate_addr = NULL;
signal (SIGHUP, SIG_DFL);
char *blkbuf, *save_ptr, *test_ptr, *read_ptr;
char * ptr;
int try, i;
- long got, used2, written;
+ long got, used2, written, save_currently_testing;
struct saved_blk_record *test_record;
- int num_saved;
+ /* This is static to prevent being clobbered by the longjmp */
+ static int num_saved;
jmp_buf terminate_env;
errcode_t errcode;
- /* These are static to prevent being clobbered by the longjmp */
- static long buf_used = 0;
- static unsigned int bb_count = 0;
+ long buf_used;
+ unsigned int bb_count;
errcode = ext2fs_badblocks_list_iterate_begin(bb_list,&bb_iter);
if (errcode) {
/*
* Abnormal termination by a signal is handled here.
*/
-
- fprintf(stderr, _("Interrupt caught, cleaning up\n"));
+ signal (SIGALRM, SIG_IGN);
+ fprintf(stderr, _("\nInterrupt caught, cleaning up\n"));
save_ptr = blkbuf;
for (i=0; i < num_saved; i++) {
capture_terminate(terminate_env);
buf_used = 0;
+ bb_count = 0;
save_ptr = blkbuf;
test_ptr = blkbuf + (blocks_at_once * block_size);
currently_testing = from_count;
continue;
flush_bufs(dev);
+ save_currently_testing = currently_testing;
/*
* for each contiguous block that we read into the
buf_used = 0;
save_ptr = blkbuf;
test_ptr = blkbuf + (blocks_at_once * block_size);
+ currently_testing = save_currently_testing;
}
num_blocks = 0;
alarm(0);
return bb_count;
}
+static void check_mount(char *device_name)
+{
+ errcode_t retval;
+ int mount_flags;
+
+ retval = ext2fs_check_if_mounted(device_name, &mount_flags);
+ if (retval) {
+ com_err("ext2fs_check_if_mount", retval,
+ _("while determining whether %s is mounted."),
+ device_name);
+ return;
+ }
+ if (!(mount_flags & EXT2_MF_MOUNTED))
+ return;
+
+ fprintf(stderr, _("%s is mounted; "), device_name);
+ if (force) {
+ fprintf(stderr, _("badblocks forced anyway. "
+ "Hope /etc/mtab is incorrect.\n"));
+ return;
+ }
+ fprintf(stderr, _("it's not safe to run badblocks!\n"));
+ exit(1);
+}
+
+
int main (int argc, char ** argv)
{
int c;
unsigned int (*test_func)(int dev, unsigned long blocks_count,
int block_size, unsigned long from_count,
unsigned long blocks_at_once);
- size_t buf_size;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
if (argc && *argv)
program_name = *argv;
- while ((c = getopt (argc, argv, "b:i:o:svwnc:p:h:")) != EOF) {
+ while ((c = getopt (argc, argv, "b:fi:o:svwnc:p:h:")) != EOF) {
switch (c) {
case 'b':
block_size = strtoul (optarg, &tmp, 0);
exit (1);
}
break;
+ case 'f':
+ force++;
+ break;
case 'i':
input_file = optarg;
break;
}
if (optind <= argc-1) {
from_count = strtoul (argv[optind], &tmp, 0);
+ if (*tmp) {
+ com_err (program_name, 0, _("bad starting block - %s"),
+ argv[optind]);
+ exit (1);
+ }
} else from_count = 0;
if (from_count >= blocks_count) {
com_err (program_name, 0, _("bad blocks range: %lu-%lu"),
from_count, blocks_count);
exit (1);
}
+ if (w_flag)
+ check_mount(device_name);
+
dev = open (device_name, w_flag ? O_RDWR : O_RDONLY);
if (dev == -1)
{
if (in) {
for(;;) {
- switch(fscanf (in, "%lu\n", &next_bad)) {
+ switch(fscanf (in, "%u\n", &next_bad)) {
case 0:
com_err (program_name, 0, "input file - bad format");
exit (1);