[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

draft: Improving error handling in udpkg



Here is a patch I started on a few months ago, but I never found time
to complete it.  It tries to add more error handling to udpkg, to make
it handle out of disk space errors more gracefully.

Comments welcome, and if someone want to complete this patch, it would
be most welcome as a fix for bug #197922.

Index: status.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/udpkg/status.c,v
retrieving revision 1.27
diff -u -3 -p -u -w -r1.27 status.c
--- status.c    12 Feb 2003 03:12:39 -0000      1.27
+++ status.c    15 Sep 2003 20:42:10 -0000
@@ -1,10 +1,15 @@
 /* $Id: status.c,v 1.27 2003/02/12 03:12:39 kraai Exp $ */
 #include "udpkg.h"

+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#include <error.h>
 #include <search.h>
+#include <errno.h>

 /* Status file handling routines
  *
@@ -105,6 +110,8 @@ int read_block(FILE *f, char **ml)
                strcat(multiple_lines, " ");
                strcat(multiple_lines, buf);
        }
+       if (NULL != *ml)
+               free(*ml);
         *ml = multiple_lines;
        ungetc(ch, f);
        return EXIT_SUCCESS;
@@ -209,6 +216,21 @@ void *status_read(void)
        FILE *f;
        void *status = 0;
        struct package_t *m = 0, *p = 0, *t = 0;
+       struct stat statbuf;
+
+       /* Try to create file if it is missing */
+       if (0 > stat(STATUSFILE, &statbuf) && ENOENT == errno)
+       {
+               f = fopen(STATUSFILE, "w");
+               if (NULL != f)
+                       fclose(f);
+               else
+               {
+                       error(0, errno, "Unable to create status file %s",
+                             STATUSFILE);
+                       return 0;
+               }
+       }

        if ((f = fopen(STATUSFILE, "r")) == NULL)
        {
Index: udpkg.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/udpkg/udpkg.c,v
retrieving revision 1.38
diff -u -3 -p -u -w -r1.38 udpkg.c
--- udpkg.c     26 Jun 2003 14:43:16 -0000      1.38
+++ udpkg.c     15 Sep 2003 20:42:10 -0000
@@ -26,8 +26,6 @@ static int do_system(const char *cmd)
        DPRINTF("cmd is %s\n", cmd);
        return system(cmd);
 }
-#else
-#define do_system(cmd) system(cmd)
 #endif

 static int is_file(const char *fn)
@@ -126,7 +124,7 @@ static int dpkg_doconfigure(struct packa
        if (is_file(config))
        {
                snprintf(buf, sizeof(buf), "exec %s configure", config);
-               if ((r = do_system(buf)) != 0)
+               if ((r = SYSTEM(buf)) != 0)
                {
                        fprintf(stderr, "config exited with status %d\n", r);
                        pkg->status |= STATUS_STATUSHALFCONFIGURED;
@@ -138,7 +136,7 @@ static int dpkg_doconfigure(struct packa
        if (is_file(postinst))
        {
                snprintf(buf, sizeof(buf), "exec %s configure", postinst);
-               if ((r = do_system(buf)) != 0)
+               if ((r = SYSTEM(buf)) != 0)
                {
                        fprintf(stderr, "%s's postinst exited with status %d\n",                                 pkg->package, r);
@@ -168,7 +166,8 @@ static int dpkg_dounpack(struct package_

        cwd = getcwd(0, 0);
        chdir("/");
-       snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|tar -xzf -", pkg->file);
+       snprintf(buf, sizeof(buf),
+                "ar -p %s data.tar.gz|tar -xzf -", pkg->file);
        if (SYSTEM(buf) == 0)
        {
                /* Installs the package scripts into the info directory */
@@ -261,6 +260,8 @@ static int dpkg_dounpack(struct package_
                else
                        pkg->status |= STATUS_STATUSHALFINSTALLED;
        }
+       else
+               r = 1;
        chdir(cwd);
        return r;
 }
@@ -290,7 +291,8 @@ static int dpkg_unpackcontrol(struct pac
        DPRINTF("dir = %s\n", buf);
        if (mkdir(buf, S_IRWXU) == 0 && chdir(buf) == 0)
        {
-               snprintf(buf, sizeof(buf), "ar -p %s control.tar.gz|tar -xzf -",
+               snprintf(buf, sizeof(buf),
+                        "ar -p %s control.tar.gz | tar -xzf -",
                        pkg->file);
                if (SYSTEM(buf) == 0)
                {
@@ -321,7 +323,8 @@ static int dpkg_unpack(struct package_t

        for (pkg = pkgs; pkg != 0; pkg = pkg->next)
        {
-               dpkg_unpackcontrol(pkg);
+               r = dpkg_unpackcontrol(pkg);
+               if (0 == r)
                r = dpkg_dounpack(pkg);
                if (r != 0) break;
        }
@@ -373,6 +376,7 @@ static int dpkg_install(struct package_t
                        perror(p->file);
                        /* force loop break, and prevents further ops */
                        pkgs = 0;
+                       return 1; /* unpack failed, time to stop */
                }

        /* Stage 2: resolve dependencies */
@@ -397,6 +401,7 @@ static int dpkg_install(struct package_t
                if (dpkg_doinstall(p) != 0)
                {
                        perror(p->file);
+                       return 1;
                }
        }



Reply to: