loadkeys: Do not call exit() the parser
authorAlexey Gladkov <gladkov.alexey@gmail.com>
Sun, 8 Jul 2012 21:12:47 +0000 (01:12 +0400)
committerAlexey Gladkov <gladkov.alexey@gmail.com>
Sun, 8 Jul 2012 21:12:47 +0000 (01:12 +0400)
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
src/loadkeys.c
src/loadkeys.y

index a826a29..9d93bac 100644 (file)
@@ -446,7 +446,7 @@ static int defkeys(int fd, int kbd_mode)
                if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
                        lkerror(_("KDSKBMODE: %s: could not switch to Unicode mode"),
                                strerror(errno));
-                       exit(EXIT_FAILURE);
+                       goto fail;
                }
        }
 
@@ -493,7 +493,7 @@ static int defkeys(int fd, int kbd_mode)
                                if (errno != EINVAL) {
                                        lkerror(_("KDSKBENT: %s: could not deallocate keymap %d"),
                                                strerror(errno), i);
-                                       exit(EXIT_FAILURE);
+                                       goto fail;
                                }
                                /* probably an old kernel */
                                /* clear keymap by hand */
@@ -508,7 +508,7 @@ static int defkeys(int fd, int kbd_mode)
 
                                                lkerror(_("KDSKBENT: %s: cannot deallocate or clear keymap"),
                                                        strerror(errno));
-                                               exit(EXIT_FAILURE);
+                                               goto fail;
                                        }
                                }
                        }
@@ -518,10 +518,12 @@ static int defkeys(int fd, int kbd_mode)
        if (optu && ioctl(fd, KDSKBMODE, kbd_mode)) {
                lkerror(_("KDSKBMODE: %s: could not return to original keyboard mode"),
                        strerror(errno));
-               exit(EXIT_FAILURE);
+               goto fail;
        }
 
        return ct;
+
+ fail: return -1;
 }
 
 static void freekeys(void)
@@ -535,7 +537,8 @@ static void freekeys(void)
        }
 }
 
-static char *ostr(char *s)
+static char *
+ostr(char *s)
 {
        int lth = strlen(s);
        char *ns0 = malloc(4 * lth + 1);
@@ -543,7 +546,7 @@ static char *ostr(char *s)
 
        if (ns == NULL) {
                lkerror(_("out of memory"));
-               exit(EXIT_FAILURE);
+               return NULL;
        }
 
        while (*s) {
@@ -567,7 +570,8 @@ static char *ostr(char *s)
        return ns0;
 }
 
-static int deffuncs(int fd)
+static int
+deffuncs(int fd)
 {
        int i, ct = 0;
        char *ptr, *s;
@@ -579,6 +583,8 @@ static int deffuncs(int fd)
                        strcpy((char *)kbs_buf.kb_string, ptr);
                        if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs_buf)) {
                                s = ostr((char *)kbs_buf.kb_string);
+                               if (s == NULL)
+                                       return -1;
                                lkerror(_("failed to bind string '%s' to function %s"),
                                        s, syms[KT_FN].table[kbs_buf.kb_func]);
                                free(s);
@@ -598,7 +604,8 @@ static int deffuncs(int fd)
        return ct;
 }
 
-static int defdiacs(int fd)
+static int
+defdiacs(int fd)
 {
        unsigned int i, count;
        struct kbdiacrs kd;
@@ -621,10 +628,8 @@ static int defdiacs(int fd)
                        kdu.kbdiacruc[i].result = accent_table[i].result;
                }
 
-               if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu)) {
-                       lkerror("KDSKBDIACRUC: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
-               }
+               if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu))
+                       goto fail2;
        } else
 #endif
        {
@@ -635,14 +640,19 @@ static int defdiacs(int fd)
                        kd.kbdiacr[i].result = accent_table[i].result;
                }
 
-               if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd)) {
-                       perror("KDSKBDIACR");
-                       lkerror("KDSKBDIACR: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
-               }
+               if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd))
+                       goto fail1;
        }
 
        return kd.kb_cnt;
+
+ fail1:        lkerror("KDSKBDIACR: %s", strerror(errno));
+       return -1;
+
+#ifdef KDSKBDIACRUC
+ fail2:        lkerror("KDSKBDIACRUC: %s", strerror(errno));
+       return -1;
+#endif
 }
 
 static int
@@ -724,12 +734,13 @@ do_constant(void)
        return -1;
 }
 
-static void loadkeys(int fd, int kbd_mode)
+static int
+loadkeys(int fd, int kbd_mode)
 {
-       int keyct, funcct, diacct = 0;
+       int keyct, funcct, diacct;
 
-       keyct = defkeys(fd, kbd_mode);
-       funcct = deffuncs(fd);
+       if ((keyct = defkeys(fd, kbd_mode)) < 0 || (funcct = deffuncs(fd)) < 0)
+               return -1;
 
        lkverbose(1, _("\nChanged %d %s and %d %s"),
                keyct, (keyct == 1) ? _("key") : _("keys"),
@@ -738,6 +749,9 @@ static void loadkeys(int fd, int kbd_mode)
        if (accent_table_size > 0 || nocompose) {
                diacct = defdiacs(fd);
 
+               if (diacct < 0)
+                       return -1;
+
                lkverbose(1, _("Loaded %d compose %s"),
                        diacct, (diacct == 1) ? _("definition") : _("definitions"));
 
@@ -745,7 +759,7 @@ static void loadkeys(int fd, int kbd_mode)
                lkverbose(1, _("(No change in compose definitions)"));
        }
 
-       freekeys();
+       return 0;
 }
 
 static int
@@ -875,7 +889,7 @@ outchar(FILE *fd, unsigned char c, int comma)
        fprintf(fd, comma ? "', " : "'");
 }
 
-static void
+static int
 mktable(FILE *fd)
 {
        int j;
@@ -996,9 +1010,11 @@ mktable(FILE *fd)
                fprintf(fd, "};\n\n");
        }
        fprintf(fd, "unsigned int accent_table_size = %d;\n", accent_table_size);
+       return 0;
 }
 
-static void attr_noreturn bkeymap(void)
+static int
+bkeymap(void)
 {
        int i, j;
 
@@ -1022,18 +1038,16 @@ static void attr_noreturn bkeymap(void)
                        }
                }
        }
-       freekeys();
-       exit(0);
+       return 0;
 
  fail: lkerror(_("Error writing map to file"));
-       freekeys();
-       exit(1);
+       return -1;
 }
 
 
 
 /* Line 189 of yacc.c  */
-#line 1037 "loadkeys.c"
+#line 1051 "loadkeys.c"
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
@@ -1145,7 +1159,7 @@ typedef int YYSTYPE;
 
 
 /* Line 264 of yacc.c  */
-#line 1149 "loadkeys.c"
+#line 1163 "loadkeys.c"
 
 #ifdef short
 # undef short
@@ -1450,12 +1464,12 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   977,   977,   978,   980,   981,   982,   983,   984,   985,
-     986,   987,   988,   989,   991,   997,  1002,  1008,  1013,  1019,
-    1024,  1025,  1027,  1035,  1041,  1055,  1060,  1066,  1067,  1069,
-    1069,  1077,  1083,  1084,  1086,  1087,  1088,  1089,  1090,  1091,
-    1092,  1093,  1094,  1096,  1151,  1152,  1154,  1164,  1165,  1166,
-    1167,  1168,  1169
+       0,   991,   991,   992,   994,   995,   996,   997,   998,   999,
+    1000,  1001,  1002,  1003,  1005,  1011,  1016,  1022,  1027,  1033,
+    1038,  1039,  1041,  1049,  1055,  1069,  1074,  1080,  1081,  1083,
+    1083,  1091,  1097,  1098,  1100,  1101,  1102,  1103,  1104,  1105,
+    1106,  1107,  1108,  1110,  1165,  1166,  1168,  1178,  1179,  1180,
+    1181,  1182,  1183
 };
 #endif
 
@@ -2427,7 +2441,7 @@ yyreduce:
         case 14:
 
 /* Line 1464 of yacc.c  */
-#line 992 "loadkeys.y"
+#line 1006 "loadkeys.y"
     {
                                if (set_charset((char *) kbs_buf.kb_string))
                                        YYERROR;
@@ -2437,7 +2451,7 @@ yyreduce:
   case 15:
 
 /* Line 1464 of yacc.c  */
-#line 998 "loadkeys.y"
+#line 1012 "loadkeys.y"
     {
                                alt_is_meta = 1;
                        }
@@ -2446,7 +2460,7 @@ yyreduce:
   case 16:
 
 /* Line 1464 of yacc.c  */
-#line 1003 "loadkeys.y"
+#line 1017 "loadkeys.y"
     {
                                if (strings_as_usual() == -1)
                                        YYERROR;
@@ -2456,7 +2470,7 @@ yyreduce:
   case 17:
 
 /* Line 1464 of yacc.c  */
-#line 1009 "loadkeys.y"
+#line 1023 "loadkeys.y"
     {
                                if (compose_as_usual((char *) kbs_buf.kb_string) == -1)
                                        YYERROR;
@@ -2466,7 +2480,7 @@ yyreduce:
   case 18:
 
 /* Line 1464 of yacc.c  */
-#line 1014 "loadkeys.y"
+#line 1028 "loadkeys.y"
     {
                                if (compose_as_usual(0) == -1)
                                        YYERROR;
@@ -2476,7 +2490,7 @@ yyreduce:
   case 19:
 
 /* Line 1464 of yacc.c  */
-#line 1020 "loadkeys.y"
+#line 1034 "loadkeys.y"
     {
                                keymaps_line_seen = 1;
                        }
@@ -2485,7 +2499,7 @@ yyreduce:
   case 22:
 
 /* Line 1464 of yacc.c  */
-#line 1028 "loadkeys.y"
+#line 1042 "loadkeys.y"
     {
                                int i;
                                for (i = (yyvsp[(1) - (3)]); i <= (yyvsp[(3) - (3)]); i++) {
@@ -2498,7 +2512,7 @@ yyreduce:
   case 23:
 
 /* Line 1464 of yacc.c  */
-#line 1036 "loadkeys.y"
+#line 1050 "loadkeys.y"
     {
                                if (addmap((yyvsp[(1) - (1)]),1) == -1)
                                        YYERROR;
@@ -2508,7 +2522,7 @@ yyreduce:
   case 24:
 
 /* Line 1464 of yacc.c  */
-#line 1042 "loadkeys.y"
+#line 1056 "loadkeys.y"
     {
                                if (KTYP((yyvsp[(2) - (5)])) != KT_FN) {
                                        snprintf(errmsg, sizeof(errmsg),
@@ -2526,7 +2540,7 @@ yyreduce:
   case 25:
 
 /* Line 1464 of yacc.c  */
-#line 1056 "loadkeys.y"
+#line 1070 "loadkeys.y"
     {
                                if (compose((yyvsp[(2) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(5) - (6)])) == -1)
                                        YYERROR;
@@ -2536,7 +2550,7 @@ yyreduce:
   case 26:
 
 /* Line 1464 of yacc.c  */
-#line 1061 "loadkeys.y"
+#line 1075 "loadkeys.y"
     {
                                if (compose((yyvsp[(2) - (6)]), (yyvsp[(3) - (6)]), (yyvsp[(5) - (6)])) == -1)
                                        YYERROR;
@@ -2546,21 +2560,21 @@ yyreduce:
   case 27:
 
 /* Line 1464 of yacc.c  */
-#line 1066 "loadkeys.y"
+#line 1080 "loadkeys.y"
     {  (yyval) = (yyvsp[(1) - (1)]);           }
     break;
 
   case 28:
 
 /* Line 1464 of yacc.c  */
-#line 1067 "loadkeys.y"
+#line 1081 "loadkeys.y"
     {  (yyval) = (yyvsp[(1) - (1)]) ^ 0xf000;  }
     break;
 
   case 29:
 
 /* Line 1464 of yacc.c  */
-#line 1069 "loadkeys.y"
+#line 1083 "loadkeys.y"
     {
                                mod = 0;
                        }
@@ -2569,7 +2583,7 @@ yyreduce:
   case 30:
 
 /* Line 1464 of yacc.c  */
-#line 1073 "loadkeys.y"
+#line 1087 "loadkeys.y"
     {
                                if (addkey((yyvsp[(4) - (7)]), mod, (yyvsp[(6) - (7)])) == -1)
                                        YYERROR;
@@ -2579,7 +2593,7 @@ yyreduce:
   case 31:
 
 /* Line 1464 of yacc.c  */
-#line 1078 "loadkeys.y"
+#line 1092 "loadkeys.y"
     {
                                if (addkey((yyvsp[(3) - (6)]), 0, (yyvsp[(5) - (6)])) == -1)
                                        YYERROR;
@@ -2589,70 +2603,70 @@ yyreduce:
   case 34:
 
 /* Line 1464 of yacc.c  */
-#line 1086 "loadkeys.y"
+#line 1100 "loadkeys.y"
     { mod |= M_SHIFT;  }
     break;
 
   case 35:
 
 /* Line 1464 of yacc.c  */
-#line 1087 "loadkeys.y"
+#line 1101 "loadkeys.y"
     { mod |= M_CTRL;   }
     break;
 
   case 36:
 
 /* Line 1464 of yacc.c  */
-#line 1088 "loadkeys.y"
+#line 1102 "loadkeys.y"
     { mod |= M_ALT;            }
     break;
 
   case 37:
 
 /* Line 1464 of yacc.c  */
-#line 1089 "loadkeys.y"
+#line 1103 "loadkeys.y"
     { mod |= M_ALTGR;  }
     break;
 
   case 38:
 
 /* Line 1464 of yacc.c  */
-#line 1090 "loadkeys.y"
+#line 1104 "loadkeys.y"
     { mod |= M_SHIFTL; }
     break;
 
   case 39:
 
 /* Line 1464 of yacc.c  */
-#line 1091 "loadkeys.y"
+#line 1105 "loadkeys.y"
     { mod |= M_SHIFTR; }
     break;
 
   case 40:
 
 /* Line 1464 of yacc.c  */
-#line 1092 "loadkeys.y"
+#line 1106 "loadkeys.y"
     { mod |= M_CTRLL;  }
     break;
 
   case 41:
 
 /* Line 1464 of yacc.c  */
-#line 1093 "loadkeys.y"
+#line 1107 "loadkeys.y"
     { mod |= M_CTRLR;  }
     break;
 
   case 42:
 
 /* Line 1464 of yacc.c  */
-#line 1094 "loadkeys.y"
+#line 1108 "loadkeys.y"
     { mod |= M_CAPSSHIFT;      }
     break;
 
   case 43:
 
 /* Line 1464 of yacc.c  */
-#line 1097 "loadkeys.y"
+#line 1111 "loadkeys.y"
     {
                                int i, j, keycode;
 
@@ -2710,7 +2724,7 @@ yyreduce:
   case 46:
 
 /* Line 1464 of yacc.c  */
-#line 1155 "loadkeys.y"
+#line 1169 "loadkeys.y"
     {
                                if (rvalct >= MAX_NR_KEYMAPS) {
                                        snprintf(errmsg, sizeof(errmsg),
@@ -2724,49 +2738,49 @@ yyreduce:
   case 47:
 
 /* Line 1464 of yacc.c  */
-#line 1164 "loadkeys.y"
+#line 1178 "loadkeys.y"
     { (yyval) = convert_code((yyvsp[(1) - (1)]), TO_AUTO);             }
     break;
 
   case 48:
 
 /* Line 1464 of yacc.c  */
-#line 1165 "loadkeys.y"
+#line 1179 "loadkeys.y"
     { (yyval) = add_capslock((yyvsp[(2) - (2)]));                      }
     break;
 
   case 49:
 
 /* Line 1464 of yacc.c  */
-#line 1166 "loadkeys.y"
+#line 1180 "loadkeys.y"
     { (yyval) = convert_code((yyvsp[(1) - (1)])^0xf000, TO_AUTO);      }
     break;
 
   case 50:
 
 /* Line 1464 of yacc.c  */
-#line 1167 "loadkeys.y"
+#line 1181 "loadkeys.y"
     { (yyval) = add_capslock((yyvsp[(2) - (2)])^0xf000);                       }
     break;
 
   case 51:
 
 /* Line 1464 of yacc.c  */
-#line 1168 "loadkeys.y"
+#line 1182 "loadkeys.y"
     { (yyval) = (yyvsp[(1) - (1)]);                                    }
     break;
 
   case 52:
 
 /* Line 1464 of yacc.c  */
-#line 1169 "loadkeys.y"
+#line 1183 "loadkeys.y"
     { (yyval) = add_capslock((yyvsp[(2) - (2)]));                      }
     break;
 
 
 
 /* Line 1464 of yacc.c  */
-#line 2770 "loadkeys.c"
+#line 2784 "loadkeys.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -2978,10 +2992,12 @@ yyreturn:
 
 
 /* Line 1684 of yacc.c  */
-#line 1171 "loadkeys.y"
+#line 1185 "loadkeys.y"
 
 
-static void parse_keymap(lkfile_t *f) {
+static int
+parse_keymap(lkfile_t *f)
+{
        if (!quiet && !optm)
                lkverbose(1, _("Loading %s"), f->pathname);
 
@@ -2989,7 +3005,7 @@ static void parse_keymap(lkfile_t *f) {
 
        if (stack_push(f) == -1) {
                lkerror("%s", errmsg);
-               exit(EXIT_FAILURE);
+               return -1;
        }
 
        if (yyparse()) {
@@ -3000,8 +3016,10 @@ static void parse_keymap(lkfile_t *f) {
 
                if (!optm)
                        lkerror(_("key bindings not changed"));
-               exit(EXIT_FAILURE);
+
+               return -1;
        }
+       return 0;
 }
 
 int main(int argc, char *argv[])
@@ -3022,7 +3040,7 @@ int main(int argc, char *argv[])
                { "version",            no_argument, NULL, 'V' },
                { NULL, 0, NULL, 0 }
        };
-       int c, i;
+       int c, i, rc = -1;
        int fd;
        int kbd_mode;
        int kd_mode;
@@ -3133,12 +3151,17 @@ int main(int argc, char *argv[])
                        fprintf(stderr, _("Cannot find %s\n"), DEFMAP);
                        exit(EXIT_FAILURE);
                }
-               parse_keymap(&f);
+
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
+
 
        } else if (optind == argc) {
                f.fd = stdin;
                strcpy(f.pathname, "<stdin>");
-               parse_keymap(&f);
+
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
        }
 
        for (i = optind; argv[i]; i++) {
@@ -3148,28 +3171,30 @@ int main(int argc, char *argv[])
 
                } else if (findfile(argv[i], dirpath, suffixes, &f)) {
                        fprintf(stderr, _("cannot open file %s\n"), argv[i]);
-                       exit(EXIT_FAILURE);
+                       goto fail;
                }
 
-               parse_keymap(&f);
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
        }
 
-       if (do_constant() == -1)
-               exit(EXIT_FAILURE);
-
-       if (optb)
-               bkeymap();
+       if ((rc = do_constant()) == -1)
+               goto fail;
 
-       if (optm) {
-               mktable(stdout);
-               freekeys();
-               exit(EXIT_SUCCESS);
+       if (optb) {
+               rc = bkeymap();
+       } else if (optm) {
+               rc = mktable(stdout);
+       } else {
+               rc = loadkeys(fd, kbd_mode);
        }
 
-       loadkeys(fd, kbd_mode);
-
+ fail: freekeys();
        close(fd);
 
+       if (rc < 0)
+               exit(EXIT_FAILURE);
+
        exit(EXIT_SUCCESS);
 }
 
index 4cc44ed..69f41b8 100644 (file)
@@ -387,7 +387,7 @@ static int defkeys(int fd, int kbd_mode)
                if (ioctl(fd, KDSKBMODE, K_UNICODE)) {
                        lkerror(_("KDSKBMODE: %s: could not switch to Unicode mode"),
                                strerror(errno));
-                       exit(EXIT_FAILURE);
+                       goto fail;
                }
        }
 
@@ -434,7 +434,7 @@ static int defkeys(int fd, int kbd_mode)
                                if (errno != EINVAL) {
                                        lkerror(_("KDSKBENT: %s: could not deallocate keymap %d"),
                                                strerror(errno), i);
-                                       exit(EXIT_FAILURE);
+                                       goto fail;
                                }
                                /* probably an old kernel */
                                /* clear keymap by hand */
@@ -449,7 +449,7 @@ static int defkeys(int fd, int kbd_mode)
 
                                                lkerror(_("KDSKBENT: %s: cannot deallocate or clear keymap"),
                                                        strerror(errno));
-                                               exit(EXIT_FAILURE);
+                                               goto fail;
                                        }
                                }
                        }
@@ -459,10 +459,12 @@ static int defkeys(int fd, int kbd_mode)
        if (optu && ioctl(fd, KDSKBMODE, kbd_mode)) {
                lkerror(_("KDSKBMODE: %s: could not return to original keyboard mode"),
                        strerror(errno));
-               exit(EXIT_FAILURE);
+               goto fail;
        }
 
        return ct;
+
+ fail: return -1;
 }
 
 static void freekeys(void)
@@ -476,7 +478,8 @@ static void freekeys(void)
        }
 }
 
-static char *ostr(char *s)
+static char *
+ostr(char *s)
 {
        int lth = strlen(s);
        char *ns0 = malloc(4 * lth + 1);
@@ -484,7 +487,7 @@ static char *ostr(char *s)
 
        if (ns == NULL) {
                lkerror(_("out of memory"));
-               exit(EXIT_FAILURE);
+               return NULL;
        }
 
        while (*s) {
@@ -508,7 +511,8 @@ static char *ostr(char *s)
        return ns0;
 }
 
-static int deffuncs(int fd)
+static int
+deffuncs(int fd)
 {
        int i, ct = 0;
        char *ptr, *s;
@@ -520,6 +524,8 @@ static int deffuncs(int fd)
                        strcpy((char *)kbs_buf.kb_string, ptr);
                        if (ioctl(fd, KDSKBSENT, (unsigned long)&kbs_buf)) {
                                s = ostr((char *)kbs_buf.kb_string);
+                               if (s == NULL)
+                                       return -1;
                                lkerror(_("failed to bind string '%s' to function %s"),
                                        s, syms[KT_FN].table[kbs_buf.kb_func]);
                                free(s);
@@ -539,7 +545,8 @@ static int deffuncs(int fd)
        return ct;
 }
 
-static int defdiacs(int fd)
+static int
+defdiacs(int fd)
 {
        unsigned int i, count;
        struct kbdiacrs kd;
@@ -562,10 +569,8 @@ static int defdiacs(int fd)
                        kdu.kbdiacruc[i].result = accent_table[i].result;
                }
 
-               if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu)) {
-                       lkerror("KDSKBDIACRUC: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
-               }
+               if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdu))
+                       goto fail2;
        } else
 #endif
        {
@@ -576,14 +581,19 @@ static int defdiacs(int fd)
                        kd.kbdiacr[i].result = accent_table[i].result;
                }
 
-               if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd)) {
-                       perror("KDSKBDIACR");
-                       lkerror("KDSKBDIACR: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
-               }
+               if (ioctl(fd, KDSKBDIACR, (unsigned long)&kd))
+                       goto fail1;
        }
 
        return kd.kb_cnt;
+
+ fail1:        lkerror("KDSKBDIACR: %s", strerror(errno));
+       return -1;
+
+#ifdef KDSKBDIACRUC
+ fail2:        lkerror("KDSKBDIACRUC: %s", strerror(errno));
+       return -1;
+#endif
 }
 
 static int
@@ -665,12 +675,13 @@ do_constant(void)
        return -1;
 }
 
-static void loadkeys(int fd, int kbd_mode)
+static int
+loadkeys(int fd, int kbd_mode)
 {
-       int keyct, funcct, diacct = 0;
+       int keyct, funcct, diacct;
 
-       keyct = defkeys(fd, kbd_mode);
-       funcct = deffuncs(fd);
+       if ((keyct = defkeys(fd, kbd_mode)) < 0 || (funcct = deffuncs(fd)) < 0)
+               return -1;
 
        lkverbose(1, _("\nChanged %d %s and %d %s"),
                keyct, (keyct == 1) ? _("key") : _("keys"),
@@ -679,6 +690,9 @@ static void loadkeys(int fd, int kbd_mode)
        if (accent_table_size > 0 || nocompose) {
                diacct = defdiacs(fd);
 
+               if (diacct < 0)
+                       return -1;
+
                lkverbose(1, _("Loaded %d compose %s"),
                        diacct, (diacct == 1) ? _("definition") : _("definitions"));
 
@@ -686,7 +700,7 @@ static void loadkeys(int fd, int kbd_mode)
                lkverbose(1, _("(No change in compose definitions)"));
        }
 
-       freekeys();
+       return 0;
 }
 
 static int
@@ -816,7 +830,7 @@ outchar(FILE *fd, unsigned char c, int comma)
        fprintf(fd, comma ? "', " : "'");
 }
 
-static void
+static int
 mktable(FILE *fd)
 {
        int j;
@@ -937,9 +951,11 @@ mktable(FILE *fd)
                fprintf(fd, "};\n\n");
        }
        fprintf(fd, "unsigned int accent_table_size = %d;\n", accent_table_size);
+       return 0;
 }
 
-static void attr_noreturn bkeymap(void)
+static int
+bkeymap(void)
 {
        int i, j;
 
@@ -963,12 +979,10 @@ static void attr_noreturn bkeymap(void)
                        }
                }
        }
-       freekeys();
-       exit(0);
+       return 0;
 
  fail: lkerror(_("Error writing map to file"));
-       freekeys();
-       exit(1);
+       return -1;
 }
 
 %}
@@ -1170,7 +1184,9 @@ rvalue            : NUMBER        { $$ = convert_code($1, TO_AUTO);               }
                ;
 %%
 
-static void parse_keymap(lkfile_t *f) {
+static int
+parse_keymap(lkfile_t *f)
+{
        if (!quiet && !optm)
                lkverbose(1, _("Loading %s"), f->pathname);
 
@@ -1178,7 +1194,7 @@ static void parse_keymap(lkfile_t *f) {
 
        if (stack_push(f) == -1) {
                lkerror("%s", errmsg);
-               exit(EXIT_FAILURE);
+               return -1;
        }
 
        if (yyparse()) {
@@ -1189,8 +1205,10 @@ static void parse_keymap(lkfile_t *f) {
 
                if (!optm)
                        lkerror(_("key bindings not changed"));
-               exit(EXIT_FAILURE);
+
+               return -1;
        }
+       return 0;
 }
 
 int main(int argc, char *argv[])
@@ -1211,7 +1229,7 @@ int main(int argc, char *argv[])
                { "version",            no_argument, NULL, 'V' },
                { NULL, 0, NULL, 0 }
        };
-       int c, i;
+       int c, i, rc = -1;
        int fd;
        int kbd_mode;
        int kd_mode;
@@ -1322,12 +1340,17 @@ int main(int argc, char *argv[])
                        fprintf(stderr, _("Cannot find %s\n"), DEFMAP);
                        exit(EXIT_FAILURE);
                }
-               parse_keymap(&f);
+
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
+
 
        } else if (optind == argc) {
                f.fd = stdin;
                strcpy(f.pathname, "<stdin>");
-               parse_keymap(&f);
+
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
        }
 
        for (i = optind; argv[i]; i++) {
@@ -1337,27 +1360,29 @@ int main(int argc, char *argv[])
 
                } else if (findfile(argv[i], dirpath, suffixes, &f)) {
                        fprintf(stderr, _("cannot open file %s\n"), argv[i]);
-                       exit(EXIT_FAILURE);
+                       goto fail;
                }
 
-               parse_keymap(&f);
+               if ((rc = parse_keymap(&f)) == -1)
+                       goto fail;
        }
 
-       if (do_constant() == -1)
-               exit(EXIT_FAILURE);
-
-       if (optb)
-               bkeymap();
+       if ((rc = do_constant()) == -1)
+               goto fail;
 
-       if (optm) {
-               mktable(stdout);
-               freekeys();
-               exit(EXIT_SUCCESS);
+       if (optb) {
+               rc = bkeymap();
+       } else if (optm) {
+               rc = mktable(stdout);
+       } else {
+               rc = loadkeys(fd, kbd_mode);
        }
 
-       loadkeys(fd, kbd_mode);
-
+ fail: freekeys();
        close(fd);
 
+       if (rc < 0)
+               exit(EXIT_FAILURE);
+
        exit(EXIT_SUCCESS);
 }