diff --git a/sbin/geom/class/part/geom_part.c b/sbin/geom/class/part/geom_part.c index 2b56b2978b31..01b7fa437a89 100644 --- a/sbin/geom/class/part/geom_part.c +++ b/sbin/geom/class/part/geom_part.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ uint32_t PUBSYM(version) = 0; static char sstart[32]; static char ssize[32]; +volatile sig_atomic_t undo_restore; #define GPART_AUTOFILL "*" #define GPART_FLAGS "C" @@ -756,6 +758,12 @@ skip_line(const char *p) return (1); } +static void +gpart_sighndl(int sig __unused) +{ + undo_restore = 1; +} + static void gpart_restore(struct gctl_req *req, unsigned int fl __unused) { @@ -763,6 +771,7 @@ gpart_restore(struct gctl_req *req, unsigned int fl __unused) struct gclass *classp; struct gctl_req *r; struct ggeom *gp; + struct sigaction si_sa; const char *s, *flags, *errstr, *label; char **ap, *argv[6], line[BUFSIZ], *pline; int error, forced, i, l, nargs, created, rl; @@ -786,6 +795,13 @@ gpart_restore(struct gctl_req *req, unsigned int fl __unused) geom_deletetree(&mesh); errx(EXIT_FAILURE, "Class %s not found.", s); } + + sigemptyset(&si_sa.sa_mask); + si_sa.sa_flags = 0; + si_sa.sa_handler = gpart_sighndl; + if (sigaction(SIGINT, &si_sa, 0) == -1) + err(EXIT_FAILURE, "sigaction SIGINT"); + if (forced) { /* destroy existent partition table before restore */ for (i = 0; i < nargs; i++) { @@ -811,7 +827,8 @@ gpart_restore(struct gctl_req *req, unsigned int fl __unused) } } created = 0; - while (fgets(line, sizeof(line) - 1, stdin)) { + while (undo_restore == 0 && + fgets(line, sizeof(line) - 1, stdin) != NULL) { /* Format of backup entries: * * [label] ['['attrib[,attrib]']'] @@ -920,6 +937,8 @@ gpart_restore(struct gctl_req *req, unsigned int fl __unused) } } } + if (undo_restore) + goto backout; /* commit changes if needed */ if (strchr(flags, 'C') != NULL) { for (i = 0; i < nargs; i++) {