OSDN Git Service

Re-add Android makefiles from AOSP master
[android-x86/external-e2fsprogs.git] / e2fsck / ehandler.c
1 /*
2  * ehandler.c --- handle bad block errors which come up during the
3  *      course of an e2fsck session.
4  *
5  * Copyright (C) 1994 Theodore Ts'o.  This file may be redistributed
6  * under the terms of the GNU Public License.
7  */
8
9 #include "config.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <termios.h>
15
16 #include "e2fsck.h"
17
18 #include <sys/time.h>
19 #include <sys/resource.h>
20
21 static const char *operation;
22
23 static errcode_t e2fsck_handle_read_error(io_channel channel,
24                                           unsigned long block,
25                                           int count,
26                                           void *data,
27                                           size_t size EXT2FS_ATTR((unused)),
28                                           int actual EXT2FS_ATTR((unused)),
29                                           errcode_t error)
30 {
31         int     i;
32         char    *p;
33         ext2_filsys fs = (ext2_filsys) channel->app_data;
34         e2fsck_t ctx;
35
36         ctx = (e2fsck_t) fs->priv_data;
37         if (ctx->flags & E2F_FLAG_EXITING)
38                 return 0;
39         /*
40          * If more than one block was read, try reading each block
41          * separately.  We could use the actual bytes read to figure
42          * out where to start, but we don't bother.
43          */
44         if (count > 1) {
45                 p = (char *) data;
46                 for (i=0; i < count; i++, p += channel->block_size, block++) {
47                         error = io_channel_read_blk64(channel, block,
48                                                     1, p);
49                         if (error)
50                                 return error;
51                 }
52                 return 0;
53         }
54         if (operation)
55                 printf(_("Error reading block %lu (%s) while %s.  "), block,
56                        error_message(error), operation);
57         else
58                 printf(_("Error reading block %lu (%s).  "), block,
59                        error_message(error));
60         preenhalt(ctx);
61         if (ask(ctx, _("Ignore error"), 1)) {
62                 if (ask(ctx, _("Force rewrite"), 1))
63                         io_channel_write_blk64(channel, block, count, data);
64                 return 0;
65         }
66
67         return error;
68 }
69
70 static errcode_t e2fsck_handle_write_error(io_channel channel,
71                                             unsigned long block,
72                                             int count,
73                                             const void *data,
74                                             size_t size EXT2FS_ATTR((unused)),
75                                             int actual EXT2FS_ATTR((unused)),
76                                             errcode_t error)
77 {
78         int             i;
79         const char      *p;
80         ext2_filsys fs = (ext2_filsys) channel->app_data;
81         e2fsck_t ctx;
82
83         ctx = (e2fsck_t) fs->priv_data;
84         if (ctx->flags & E2F_FLAG_EXITING)
85                 return 0;
86
87         /*
88          * If more than one block was written, try writing each block
89          * separately.  We could use the actual bytes read to figure
90          * out where to start, but we don't bother.
91          */
92         if (count > 1) {
93                 p = (const char *) data;
94                 for (i=0; i < count; i++, p += channel->block_size, block++) {
95                         error = io_channel_write_blk64(channel, block,
96                                                      1, p);
97                         if (error)
98                                 return error;
99                 }
100                 return 0;
101         }
102
103         if (operation)
104                 printf(_("Error writing block %lu (%s) while %s.  "), block,
105                        error_message(error), operation);
106         else
107                 printf(_("Error writing block %lu (%s).  "), block,
108                        error_message(error));
109         preenhalt(ctx);
110         if (ask(ctx, _("Ignore error"), 1))
111                 return 0;
112
113         return error;
114 }
115
116 const char *ehandler_operation(const char *op)
117 {
118         const char *ret = operation;
119
120         operation = op;
121         return ret;
122 }
123
124 void ehandler_init(io_channel channel)
125 {
126         channel->read_error = e2fsck_handle_read_error;
127         channel->write_error = e2fsck_handle_write_error;
128 }