Sanity.
authorjbj <devnull@localhost>
Wed, 19 Mar 2003 03:00:02 +0000 (03:00 +0000)
committerjbj <devnull@localhost>
Wed, 19 Mar 2003 03:00:02 +0000 (03:00 +0000)
CVS patchset: 6705
CVS date: 2003/03/19 03:00:02

lib/cpio.c
lib/fsm.c
lib/fsm.h
lib/poptALL.c
lib/psm.c
lib/psm.h
rpmio/rpmsq.c
rpmio/rpmsq.h

index 13b34b2..c72c536 100644 (file)
@@ -77,14 +77,14 @@ int cpioTrailerWrite(FSM_t fsm)
 
     /* XXX DWRITE uses rdnb for I/O length. */
     fsm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER);
-    rc = fsmStage(fsm, FSM_DWRITE);
+    rc = fsmNext(fsm, FSM_DWRITE);
 
     /*
      * GNU cpio pads to 512 bytes here, but we don't. This may matter for
      * tape device(s) and/or concatenated cpio archives. <shrug>
      */
     if (!rc)
-       rc = fsmStage(fsm, FSM_PAD);
+       rc = fsmNext(fsm, FSM_PAD);
 
     return rc;
 }
@@ -119,11 +119,11 @@ int cpioHeaderWrite(FSM_t fsm, struct stat * st)
 
     /* XXX DWRITE uses rdnb for I/O length. */
     fsm->rdnb = PHYS_HDR_SIZE + len;
-    rc = fsmStage(fsm, FSM_DWRITE);
+    rc = fsmNext(fsm, FSM_DWRITE);
     if (!rc && fsm->rdnb != fsm->wrnb)
        rc = CPIOERR_WRITE_FAILED;
     if (!rc)
-       rc = fsmStage(fsm, FSM_PAD);
+       rc = fsmNext(fsm, FSM_PAD);
     return rc;
 }
 
@@ -137,7 +137,7 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st)
     int rc = 0;
 
     fsm->wrlen = PHYS_HDR_SIZE;
-    rc = fsmStage(fsm, FSM_DREAD);
+    rc = fsmNext(fsm, FSM_DREAD);
     if (!rc && fsm->rdnb != fsm->wrlen)
        rc = CPIOERR_READ_FAILED;
     if (rc) return rc;
@@ -175,7 +175,7 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st)
 
     {  char * t = xmalloc(nameSize + 1);
        fsm->wrlen = nameSize;
-       rc = fsmStage(fsm, FSM_DREAD);
+       rc = fsmNext(fsm, FSM_DREAD);
        if (!rc && fsm->rdnb != fsm->wrlen)
            rc = CPIOERR_BAD_HEADER;
        if (rc) {
index 94165df..b6461b1 100644 (file)
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -16,6 +16,7 @@
 #include "rpmfi.h"
 #include "rpmte.h"
 #include "rpmts.h"
+#include "rpmsq.h"
 
 #include "debug.h"
 
@@ -378,6 +379,20 @@ static /*@observer@*/ const char * dnlNextIterator(/*@null@*/ DNLI_t dnli)
 }
 /*@=boundsread@*/
 
+static void * fsmThread(void * arg)
+       /*@modifies arg @*/
+{
+    FSM_t fsm = arg;
+    return ((void *) fsmStage(fsm, fsm->nstage));
+}
+
+int fsmNext(FSM_t fsm, fileStage nstage)
+       /*@modifies fsm @*/
+{
+    fsm->nstage = nstage;
+    return rpmsqThread(fsmThread, fsm);
+}
+
 /** \ingroup payload
  * Save hard link in chain.
  * @param fsm          file state machine data
@@ -469,7 +484,7 @@ static int saveHardLink(/*@special@*/ /*@partial@*/ FSM_t fsm)
     fsm->li->linkIndex = j;
     fsm->path = _free(fsm->path);
     fsm->ix = ix;
-    rc = fsmStage(fsm, FSM_MAP);
+    rc = fsmNext(fsm, FSM_MAP);
     return rc;
 }
 /*@=boundsread@*/
@@ -749,7 +764,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
     int left = st->st_size;
     int rc = 0;
 
-    rc = fsmStage(fsm, FSM_WOPEN);
+    rc = fsmNext(fsm, FSM_WOPEN);
     if (rc)
        goto exit;
 
@@ -759,11 +774,11 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
     while (left) {
 
        fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
-       rc = fsmStage(fsm, FSM_DREAD);
+       rc = fsmNext(fsm, FSM_DREAD);
        if (rc)
            goto exit;
 
-       rc = fsmStage(fsm, FSM_WRITE);
+       rc = fsmNext(fsm, FSM_WRITE);
        if (rc)
            goto exit;
 
@@ -771,7 +786,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
 
        /* don't call this with fileSize == fileComplete */
        if (!rc && left)
-           (void) fsmStage(fsm, FSM_NOTIFY);
+           (void) fsmNext(fsm, FSM_NOTIFY);
     }
 
     if (st->st_size > 0 && (fsm->fmd5sum || fsm->md5sum)) {
@@ -797,7 +812,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
     }
 
 exit:
-    (void) fsmStage(fsm, FSM_WCLOSE);
+    (void) fsmNext(fsm, FSM_WCLOSE);
     return rc;
 }
 
@@ -857,7 +872,7 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
            (fi->apath ? fi->apath[fsm->ix] + fi->striplen : fi->bnl[fsm->ix]);
     }
 
-    rc = fsmStage(fsm, FSM_HWRITE);
+    rc = fsmNext(fsm, FSM_HWRITE);
     fsm->path = path;
     if (rc) goto exit;
 
@@ -868,7 +883,7 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
        size_t nmapped;
 #endif
 
-       rc = fsmStage(fsm, FSM_ROPEN);
+       rc = fsmNext(fsm, FSM_ROPEN);
        if (rc) goto exit;
 
        /* XXX unbuffered mmap generates *lots* of fdio debugging */
@@ -895,12 +910,12 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
 #endif
          {
            fsm->rdlen = (left > fsm->rdsize ? fsm->rdsize : left),
-           rc = fsmStage(fsm, FSM_READ);
+           rc = fsmNext(fsm, FSM_READ);
            if (rc) goto exit;
          }
 
            /* XXX DWRITE uses rdnb for I/O length. */
-           rc = fsmStage(fsm, FSM_DWRITE);
+           rc = fsmNext(fsm, FSM_DWRITE);
            if (rc) goto exit;
 
            left -= fsm->wrnb;
@@ -923,18 +938,18 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
        strcpy(fsm->rdbuf, symbuf);     /* XXX restore readlink buffer. */
 /*@=boundswrite@*/
        fsm->rdnb = strlen(symbuf);
-       rc = fsmStage(fsm, FSM_DWRITE);
+       rc = fsmNext(fsm, FSM_DWRITE);
        if (rc) goto exit;
     }
 
-    rc = fsmStage(fsm, FSM_PAD);
+    rc = fsmNext(fsm, FSM_PAD);
     if (rc) goto exit;
 
     rc = 0;
 
 exit:
     if (fsm->rfd != NULL)
-       (void) fsmStage(fsm, FSM_RCLOSE);
+       (void) fsmNext(fsm, FSM_RCLOSE);
     /*@-dependenttrans@*/
     fsm->opath = opath;
     fsm->path = path;
@@ -969,7 +984,7 @@ static int writeLinkedFile(/*@special@*/ FSM_t fsm)
        if (fsm->li->filex[i] < 0) continue;
 
        fsm->ix = fsm->li->filex[i];
-       rc = fsmStage(fsm, FSM_MAP);
+       rc = fsmNext(fsm, FSM_MAP);
 
        /* Write data after last link. */
        rc = writeFile(fsm, (i == 0));
@@ -1014,7 +1029,7 @@ static int fsmMakeLinks(/*@special@*/ FSM_t fsm)
     fsm->ix = -1;
 
     fsm->ix = fsm->li->filex[fsm->li->createdPath];
-    rc = fsmStage(fsm, FSM_MAP);
+    rc = fsmNext(fsm, FSM_MAP);
     fsm->opath = fsm->path;
     fsm->path = NULL;
     /*@-branchstate@*/
@@ -1024,15 +1039,15 @@ static int fsmMakeLinks(/*@special@*/ FSM_t fsm)
 
        fsm->ix = fsm->li->filex[i];
        fsm->path = _free(fsm->path);
-       rc = fsmStage(fsm, FSM_MAP);
+       rc = fsmNext(fsm, FSM_MAP);
        if (XFA_SKIPPING(fsm->action)) continue;
 
-       rc = fsmStage(fsm, FSM_VERIFY);
+       rc = fsmUNSAFE(fsm, FSM_VERIFY);
        if (!rc) continue;
        if (rc != CPIOERR_LSTAT_FAILED) break;
 
        /* XXX link(fsm->opath, fsm->path) */
-       rc = fsmStage(fsm, FSM_LINK);
+       rc = fsmNext(fsm, FSM_LINK);
        if (fsm->failedFile && rc != 0 && *fsm->failedFile == NULL) {
            ec = rc;
 /*@-boundswrite@*/
@@ -1087,9 +1102,9 @@ static int fsmCommitLinks(/*@special@*/ FSM_t fsm)
     for (i = 0; i < fsm->li->nlink; i++) {
        if (fsm->li->filex[i] < 0) continue;
        fsm->ix = fsm->li->filex[i];
-       rc = fsmStage(fsm, FSM_MAP);
+       rc = fsmNext(fsm, FSM_MAP);
        if (!XFA_SKIPPING(fsm->action))
-           rc = fsmStage(fsm, FSM_COMMIT);
+           rc = fsmNext(fsm, FSM_COMMIT);
        fsm->path = _free(fsm->path);
        fsm->li->filex[i] = -1;
     }
@@ -1139,7 +1154,7 @@ static int fsmRmdirs(/*@special@*/ FSM_t fsm)
        do {
            if (*te == '/') {
                *te = '\0';
-               rc = fsmStage(fsm, FSM_RMDIR);
+               rc = fsmNext(fsm, FSM_RMDIR);
                *te = '/';
            }
            if (rc)
@@ -1236,7 +1251,7 @@ static int fsmMkdirs(/*@special@*/ FSM_t fsm)
                rpmfi fi = fsmGetFi(fsm);
                *te = '\0';
                st->st_mode = S_IFDIR | (fi->dperms & 07777);
-               rc = fsmStage(fsm, FSM_MKDIR);
+               rc = fsmNext(fsm, FSM_MKDIR);
                if (!rc)
                    rpmMessage(RPMMESS_DEBUG,
                        _("%s directory created with perms %04o.\n"),
@@ -1359,7 +1374,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
     case FSM_PKGINSTALL:
        while (1) {
            /* Clean fsm, free'ing memory. Read next archive header. */
-           rc = fsmStage(fsm, FSM_INIT);
+           rc = fsmUNSAFE(fsm, FSM_INIT);
 
            /* Exit on end-of-payload. */
            if (rc == CPIOERR_HDR_TRAILER) {
@@ -1370,21 +1385,21 @@ int fsmStage(FSM_t fsm, fileStage stage)
            /* Exit on error. */
            if (rc) {
                fsm->postpone = 1;
-               (void) fsmStage(fsm, FSM_UNDO);
+               (void) fsmNext(fsm, FSM_UNDO);
                /*@loopbreak@*/ break;
            }
 
            /* Extract file from archive. */
-           rc = fsmStage(fsm, FSM_PROCESS);
+           rc = fsmNext(fsm, FSM_PROCESS);
            if (rc) {
-               (void) fsmStage(fsm, FSM_UNDO);
+               (void) fsmNext(fsm, FSM_UNDO);
                /*@loopbreak@*/ break;
            }
 
            /* Notify on success. */
-           (void) fsmStage(fsm, FSM_NOTIFY);
+           (void) fsmNext(fsm, FSM_NOTIFY);
 
-           rc = fsmStage(fsm, FSM_FINI);
+           rc = fsmNext(fsm, FSM_FINI);
            if (rc) {
                /*@loopbreak@*/ break;
            }
@@ -1394,7 +1409,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
     case FSM_PKGCOMMIT:
        while (1) {
            /* Clean fsm, free'ing memory. */
-           rc = fsmStage(fsm, FSM_INIT);
+           rc = fsmUNSAFE(fsm, FSM_INIT);
 
            /* Exit on end-of-payload. */
            if (rc == CPIOERR_HDR_TRAILER) {
@@ -1403,14 +1418,14 @@ int fsmStage(FSM_t fsm, fileStage stage)
            }
 
            /* Rename/erase next item. */
-           if (fsmStage(fsm, FSM_FINI))
+           if (fsmNext(fsm, FSM_FINI))
                /*@loopbreak@*/ break;
        }
        break;
     case FSM_PKGBUILD:
        while (1) {
 
-           rc = fsmStage(fsm, FSM_INIT);
+           rc = fsmUNSAFE(fsm, FSM_INIT);
 
            /* Exit on end-of-payload. */
            if (rc == CPIOERR_HDR_TRAILER) {
@@ -1421,21 +1436,21 @@ int fsmStage(FSM_t fsm, fileStage stage)
            /* Exit on error. */
            if (rc) {
                fsm->postpone = 1;
-               (void) fsmStage(fsm, FSM_UNDO);
+               (void) fsmNext(fsm, FSM_UNDO);
                /*@loopbreak@*/ break;
            }
 
            /* Copy file into archive. */
-           rc = fsmStage(fsm, FSM_PROCESS);
+           rc = fsmNext(fsm, FSM_PROCESS);
            if (rc) {
-               (void) fsmStage(fsm, FSM_UNDO);
+               (void) fsmNext(fsm, FSM_UNDO);
                /*@loopbreak@*/ break;
            }
 
            /* Notify on success. */
-           (void) fsmStage(fsm, FSM_NOTIFY);
+           (void) fsmNext(fsm, FSM_NOTIFY);
 
-           if (fsmStage(fsm, FSM_FINI))
+           if (fsmNext(fsm, FSM_FINI))
                /*@loopbreak@*/ break;
        }
 
@@ -1472,7 +1487,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
        }
 
        if (!rc)
-           rc = fsmStage(fsm, FSM_TRAILER);
+           rc = fsmNext(fsm, FSM_TRAILER);
 
        break;
     case FSM_CREATE:
@@ -1507,7 +1522,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
 
        /* Detect and create directories not explicitly in package. */
        if (fsm->goal == FSM_PKGINSTALL) {
-           rc = fsmStage(fsm, FSM_MKDIRS);
+           rc = fsmNext(fsm, FSM_MKDIRS);
            if (!rc) fsm->mkdirsdone = 1;
        }
 
@@ -1524,7 +1539,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
 
        if (fsm->goal == FSM_PKGINSTALL) {
            /* Read next header from payload, checking for end-of-payload. */
-           rc = fsmStage(fsm, FSM_NEXT);
+           rc = fsmUNSAFE(fsm, FSM_NEXT);
        }
        if (rc) break;
 
@@ -1558,7 +1573,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
        }
 
        /* Generate file path. */
-       rc = fsmStage(fsm, FSM_MAP);
+       rc = fsmNext(fsm, FSM_MAP);
        if (rc) break;
 
        /* Perform lstat/stat for disk file. */
@@ -1618,7 +1633,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
     case FSM_PROCESS:
        if (fsm->postpone) {
            if (fsm->goal == FSM_PKGINSTALL)
-               rc = fsmStage(fsm, FSM_EAT);
+               rc = fsmNext(fsm, FSM_EAT);
            break;
        }
 
@@ -1655,13 +1670,13 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            const char * path = fsm->path;
            if (fsm->osuffix)
                fsm->path = fsmFsPath(fsm, st, NULL, NULL);
-           rc = fsmStage(fsm, FSM_VERIFY);
+           rc = fsmUNSAFE(fsm, FSM_VERIFY);
 
            if (rc == 0 && fsm->osuffix) {
                const char * opath = fsm->opath;
                fsm->opath = fsm->path;
                fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix);
-               rc = fsmStage(fsm, FSM_RENAME);
+               rc = fsmNext(fsm, FSM_RENAME);
                if (!rc)
                    rpmMessage(RPMMESS_WARNING,
                        _("%s saved as %s\n"), fsm->opath, fsm->path);
@@ -1676,11 +1691,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            rc = expandRegular(fsm);
        } else if (S_ISDIR(st->st_mode)) {
            mode_t st_mode = st->st_mode;
-           rc = fsmStage(fsm, FSM_VERIFY);
+           rc = fsmUNSAFE(fsm, FSM_VERIFY);
            if (rc == CPIOERR_LSTAT_FAILED) {
                st->st_mode &= ~07777;          /* XXX abuse st->st_mode */
                st->st_mode |=  00700;
-               rc = fsmStage(fsm, FSM_MKDIR);
+               rc = fsmNext(fsm, FSM_MKDIR);
                st->st_mode = st_mode;          /* XXX restore st->st_mode */
            }
        } else if (S_ISLNK(st->st_mode)) {
@@ -1692,7 +1707,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            }
 
            fsm->wrlen = st->st_size;
-           rc = fsmStage(fsm, FSM_DREAD);
+           rc = fsmNext(fsm, FSM_DREAD);
            if (!rc && fsm->rdnb != fsm->wrlen)
                rc = CPIOERR_READ_FAILED;
            if (rc) break;
@@ -1704,26 +1719,26 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            /*@-dependenttrans@*/
            fsm->opath = fsm->wrbuf;
            /*@=dependenttrans@*/
-           rc = fsmStage(fsm, FSM_VERIFY);
+           rc = fsmUNSAFE(fsm, FSM_VERIFY);
            if (rc == CPIOERR_LSTAT_FAILED)
-               rc = fsmStage(fsm, FSM_SYMLINK);
+               rc = fsmNext(fsm, FSM_SYMLINK);
            fsm->opath = opath;         /* XXX restore fsm->path */
        } else if (S_ISFIFO(st->st_mode)) {
            mode_t st_mode = st->st_mode;
            /* This mimics cpio S_ISSOCK() behavior but probably isnt' right */
-           rc = fsmStage(fsm, FSM_VERIFY);
+           rc = fsmUNSAFE(fsm, FSM_VERIFY);
            if (rc == CPIOERR_LSTAT_FAILED) {
                st->st_mode = 0000;             /* XXX abuse st->st_mode */
-               rc = fsmStage(fsm, FSM_MKFIFO);
+               rc = fsmNext(fsm, FSM_MKFIFO);
                st->st_mode = st_mode;  /* XXX restore st->st_mode */
            }
        } else if (S_ISCHR(st->st_mode) ||
                   S_ISBLK(st->st_mode) ||
     /*@-unrecog@*/ S_ISSOCK(st->st_mode) /*@=unrecog@*/)
        {
-           rc = fsmStage(fsm, FSM_VERIFY);
+           rc = fsmUNSAFE(fsm, FSM_VERIFY);
            if (rc == CPIOERR_LSTAT_FAILED)
-               rc = fsmStage(fsm, FSM_MKNOD);
+               rc = fsmNext(fsm, FSM_MKNOD);
        } else {
            /* XXX Special case /dev/log, which shouldn't be packaged anyways */
            if (!IS_DEV_LOG(fsm->path))
@@ -1756,12 +1771,12 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
        if (fsm->postpone)
            break;
        if (fsm->goal == FSM_PKGINSTALL) {
-           (void) fsmStage(fsm,
+           (void) fsmNext(fsm,
                (S_ISDIR(st->st_mode) ? FSM_RMDIR : FSM_UNLINK));
 
 #ifdef NOTYET  /* XXX remove only dirs just created, not all. */
            if (fsm->dnlx)
-               (void) fsmStage(fsm, FSM_RMDIRS);
+               (void) fsmNext(fsm, FSM_RMDIRS);
 #endif
            errno = saveerrno;
        }
@@ -1774,11 +1789,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
        if (!fsm->postpone && fsm->commit) {
            if (fsm->goal == FSM_PKGINSTALL)
                rc = ((!S_ISDIR(st->st_mode) && st->st_nlink > 1)
-                       ? fsmCommitLinks(fsm) : fsmStage(fsm, FSM_COMMIT));
+                       ? fsmCommitLinks(fsm) : fsmNext(fsm, FSM_COMMIT));
            if (fsm->goal == FSM_PKGCOMMIT)
-               rc = fsmStage(fsm, FSM_COMMIT);
+               rc = fsmNext(fsm, FSM_COMMIT);
            if (fsm->goal == FSM_PKGERASE)
-               rc = fsmStage(fsm, FSM_COMMIT);
+               rc = fsmNext(fsm, FSM_COMMIT);
        }
        fsm->path = _free(fsm->path);
        fsm->opath = _free(fsm->opath);
@@ -1796,7 +1811,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            const char * path = fsm->path;
            fsm->opath = fsmFsPath(fsm, st, NULL, NULL);
            fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix);
-           rc = fsmStage(fsm, FSM_RENAME);
+           rc = fsmNext(fsm, FSM_RENAME);
            if (!rc) {
                rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"),
                                fsm->opath, fsm->path);
@@ -1812,7 +1827,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            if (fsm->action == FA_ERASE) {
                rpmfi fi = fsmGetFi(fsm);
                if (S_ISDIR(st->st_mode)) {
-                   rc = fsmStage(fsm, FSM_RMDIR);
+                   rc = fsmNext(fsm, FSM_RMDIR);
                    if (!rc) break;
                    switch (errno) {
                    case ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
@@ -1835,7 +1850,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
                        /*@innerbreak@*/ break;
                    }
                } else {
-                   rc = fsmStage(fsm, FSM_UNLINK);
+                   rc = fsmNext(fsm, FSM_UNLINK);
                    if (!rc) break;
                    if (!(errno == ENOENT && (fsm->fflags & RPMFILE_MISSINGOK)))
                        rpmError(
@@ -1857,7 +1872,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            {
                fsm->opath = fsm->path;
                fsm->path = fsmFsPath(fsm, st, NULL, fsm->nsuffix);
-               rc = fsmStage(fsm, FSM_RENAME);
+               rc = fsmNext(fsm, FSM_RENAME);
                if (!rc && fsm->nsuffix) {
                    const char * opath = fsmFsPath(fsm, st, NULL, NULL);
                    rpmMessage(RPMMESS_WARNING, _("%s created as %s\n"),
@@ -1868,25 +1883,25 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            }
            if (S_ISLNK(st->st_mode)) {
                if (!rc && !getuid())
-                   rc = fsmStage(fsm, FSM_LCHOWN);
+                   rc = fsmNext(fsm, FSM_LCHOWN);
            } else {
                if (!rc && !getuid())
-                   rc = fsmStage(fsm, FSM_CHOWN);
+                   rc = fsmNext(fsm, FSM_CHOWN);
                if (!rc)
-                   rc = fsmStage(fsm, FSM_CHMOD);
+                   rc = fsmNext(fsm, FSM_CHMOD);
                if (!rc) {
                    time_t mtime = st->st_mtime;
                    rpmfi fi = fsmGetFi(fsm);
                    if (fi->fmtimes)
                        st->st_mtime = fi->fmtimes[fsm->ix];
-                   rc = fsmStage(fsm, FSM_UTIME);
+                   rc = fsmNext(fsm, FSM_UTIME);
                    st->st_mtime = mtime;
                }
            }
        }
 
        /* Notify on success. */
-       if (!rc)                rc = fsmStage(fsm, FSM_NOTIFY);
+       if (!rc)                rc = fsmNext(fsm, FSM_NOTIFY);
        else if (fsm->failedFile && *fsm->failedFile == NULL) {
 /*@-boundswrite@*/
            *fsm->failedFile = fsm->path;
@@ -1910,7 +1925,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
                    rc = CPIOERR_MISSING_HARDLINK;
                    if (fsm->failedFile && *fsm->failedFile == NULL) {
                        fsm->ix = fsm->li->filex[i];
-                       if (!fsmStage(fsm, FSM_MAP)) {
+                       if (!fsmNext(fsm, FSM_MAP)) {
 /*@-boundswrite@*/
                            *fsm->failedFile = fsm->path;
 /*@=boundswrite@*/
@@ -1948,9 +1963,9 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
             */
            fsm->opath = fsm->path;
            fsm->path = path;
-           rc = fsmStage(fsm, FSM_RENAME);
+           rc = fsmNext(fsm, FSM_RENAME);
            if (!rc)
-                   (void) fsmStage(fsm, FSM_UNLINK);
+                   (void) fsmNext(fsm, FSM_UNLINK);
            else
                    rc = CPIOERR_UNLINK_FAILED;
            fsm->path = fsm->opath;
@@ -1984,7 +1999,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
        }
            /* XXX shouldn't do this with commit/undo. */
        rc = 0;
-       if (fsm->stage == FSM_PROCESS) rc = fsmStage(fsm, FSM_UNLINK);
+       if (fsm->stage == FSM_PROCESS) rc = fsmNext(fsm, FSM_UNLINK);
        if (rc == 0)    rc = CPIOERR_LSTAT_FAILED;
        return (rc ? rc : CPIOERR_LSTAT_FAILED);        /* XXX HACK */
        /*@notreached@*/ break;
@@ -2143,12 +2158,12 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
            rc = CPIOERR_HDR_TRAILER;
        }
        if (!rc)
-           rc = fsmStage(fsm, FSM_POS);
+           rc = fsmNext(fsm, FSM_POS);
        break;
     case FSM_EAT:
        for (left = st->st_size; left > 0; left -= fsm->rdnb) {
            fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
-           rc = fsmStage(fsm, FSM_DREAD);
+           rc = fsmNext(fsm, FSM_DREAD);
            if (rc)
                /*@loopbreak@*/ break;
        }
@@ -2157,7 +2172,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
        left = (modulo - (fdGetCpioPos(fsm->cfd) % modulo)) % modulo;
        if (left) {
            fsm->wrlen = left;
-           (void) fsmStage(fsm, FSM_DREAD);
+           (void) fsmNext(fsm, FSM_DREAD);
        }
        break;
     case FSM_PAD:
@@ -2168,14 +2183,14 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
 /*@=boundswrite@*/
            /* XXX DWRITE uses rdnb for I/O length. */
            fsm->rdnb = left;
-           (void) fsmStage(fsm, FSM_DWRITE);
+           (void) fsmNext(fsm, FSM_DWRITE);
        }
        break;
     case FSM_TRAILER:
        rc = cpioTrailerWrite(fsm);
        break;
     case FSM_HREAD:
-       rc = fsmStage(fsm, FSM_POS);
+       rc = fsmNext(fsm, FSM_POS);
        if (!rc)
            rc = cpioHeaderRead(fsm, st);       /* Read next payload header. */
        break;
@@ -2210,7 +2225,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
     case FSM_ROPEN:
        fsm->rfd = Fopen(fsm->path, "r.ufdio");
        if (fsm->rfd == NULL || Ferror(fsm->rfd)) {
-           if (fsm->rfd != NULL)       (void) fsmStage(fsm, FSM_RCLOSE);
+           if (fsm->rfd != NULL)       (void) fsmNext(fsm, FSM_RCLOSE);
            fsm->rfd = NULL;
            rc = CPIOERR_OPEN_FAILED;
            break;
@@ -2241,7 +2256,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
     case FSM_WOPEN:
        fsm->wfd = Fopen(fsm->path, "w.ufdio");
        if (fsm->wfd == NULL || Ferror(fsm->wfd)) {
-           if (fsm->wfd != NULL)       (void) fsmStage(fsm, FSM_WCLOSE);
+           if (fsm->wfd != NULL)       (void) fsmNext(fsm, FSM_WCLOSE);
            fsm->wfd = NULL;
            rc = CPIOERR_OPEN_FAILED;
        }
index 9ca5c87..7a36c8a 100644 (file)
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -188,6 +188,7 @@ struct fsm_s {
     fileAction action;         /*!< File disposition. */
     fileStage goal;            /*!< Package state machine goal. */
     fileStage stage;           /*!< External file stage. */
+    fileStage nstage;          /*!< Next file stage. */
     struct stat sb;            /*!< Current file stat(2) info. */
     struct stat osb;           /*!< Original file stat(2) info. */
 };
@@ -290,6 +291,9 @@ int fsmMapAttrs(FSM_t fsm)
        /*@modifies fsm @*/;
 /*@=exportlocal@*/
 
+int fsmNext(FSM_t fsm, fileStage nstage)
+       /*@modifies fsm @*/;
+
 /**
  * File state machine driver.
  * @param fsm          file state machine data
@@ -300,6 +304,8 @@ int fsmStage(/*@partial@*/ FSM_t fsm, fileStage stage)
        /*@globals errno, fileSystem, internalState @*/
        /*@modifies fsm, errno, fileSystem, internalState @*/;
 
+#define        fsmUNSAFE       fsmStage
+
 #ifdef __cplusplus
 }
 #endif
index 1748612..94b3a40 100644 (file)
@@ -56,6 +56,9 @@ extern int _rpmfi_debug;
 extern int _rpmps_debug;
 
 /*@unchecked@*/
+extern int _rpmsq_debug;
+
+/*@unchecked@*/
 extern int _rpmte_debug;
 
 /*@unchecked@*/
@@ -290,6 +293,8 @@ struct poptOption rpmcliAllPoptTable[] = {
        N_("debug rpmio I/O"), NULL},
  { "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1,
        NULL, NULL},
+ { "rpmsqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsq_debug, -1,
+       NULL, NULL},
  { "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
        NULL, NULL},
  { "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,
index 5e5979d..8e522c7 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -531,9 +531,6 @@ static rpmRC runScript(rpmpsm psm, Header h, const char * sln,
     if (progArgv == NULL && script == NULL)
        return rc;
 
-    psm->sq.child = 0;
-    psm->sq.reaped = 0;
-    psm->sq.status = 0;
     psm->sq.reaper = 1;
 
     /* XXX FIXME: except for %verifyscript, rpmteNEVR can be used. */
@@ -723,10 +720,6 @@ static rpmRC runScript(rpmpsm psm, Header h, const char * sln,
            rpmMessage(RPMMESS_DEBUG, _("%s: %s(%s-%s-%s)\texecv(%s) pid %d\n"),
                        psm->stepName, sln, n, v, r,
                        argv[0], (unsigned)getpid());
-/*@-modfilesys@*/
-if (_psm_debug)
-fprintf(stderr, "      Exec: %s \"%s\"\n", sln, argv[0]);
-/*@=modfilesys@*/
            unsetenv("MALLOC_CHECK_");
            xx = execv(argv[0], (char *const *)argv);
            break;
@@ -1135,6 +1128,20 @@ rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
     return rpmpsmLink(psm, msg);
 }
 
+static void * rpmpsmThread(void * arg)
+       /*@modifies psm @*/
+{
+    rpmpsm psm = arg;
+    return ((void *) rpmpsmStage(psm, psm->nstage));
+}
+
+static int rpmpsmNext(rpmpsm psm, pkgStage nstage)
+       /*@modifies psm @*/
+{
+    psm->nstage = nstage;
+    return rpmsqThread(rpmpsmThread, psm);
+}
+
 /**
  * @todo Packages w/o files never get a callback, hence don't get displayed
  * on install with -v.
@@ -1241,7 +1248,7 @@ assert(psm->mi == NULL);
            psm->scriptArg = psm->npkgs_installed - 1;
        
            /* Retrieve installed header. */
-           rc = rpmpsmStage(psm, PSM_RPMDB_LOAD);
+           rc = rpmpsmNext(psm, PSM_RPMDB_LOAD);
 if (rc == RPMRC_OK)
 if (psm->te)
 psm->te->h = headerLink(fi->h);
@@ -1281,7 +1288,7 @@ psm->te->h = headerLink(fi->h);
 #endif
 
        /* Change root directory if requested and not already done. */
-       rc = rpmpsmStage(psm, PSM_CHROOT_IN);
+       rc = rpmpsmNext(psm, PSM_CHROOT_IN);
 
        if (psm->goal == PSM_PKGINSTALL) {
            psm->scriptTag = RPMTAG_PREIN;
@@ -1292,7 +1299,7 @@ psm->te->h = headerLink(fi->h);
            }
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
-               rc = rpmpsmStage(psm, PSM_SCRIPT);
+               rc = rpmpsmNext(psm, PSM_SCRIPT);
                if (rc != RPMRC_OK) {
                    rpmError(RPMERR_SCRIPT,
                        _("%s: %s scriptlet failed (%d), skipping %s\n"),
@@ -1311,16 +1318,16 @@ psm->te->h = headerLink(fi->h);
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
                /* Run triggers in this package other package(s) set off. */
-               rc = rpmpsmStage(psm, PSM_IMMED_TRIGGERS);
+               rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
                if (rc) break;
 
                /* Run triggers in other package(s) this package sets off. */
-               rc = rpmpsmStage(psm, PSM_TRIGGERS);
+               rc = rpmpsmNext(psm, PSM_TRIGGERS);
                if (rc) break;
            }
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN))
-               rc = rpmpsmStage(psm, PSM_SCRIPT);
+               rc = rpmpsmNext(psm, PSM_SCRIPT);
        }
        if (psm->goal == PSM_PKGSAVE) {
            int noArchiveSize = 0;
@@ -1366,7 +1373,7 @@ psm->te->h = headerLink(fi->h);
 
            /* Retrieve type of payload compression. */
            /*@-nullstate@*/    /* FIX: psm->oh may be NULL */
-           rc = rpmpsmStage(psm, PSM_RPMIO_FLAGS);
+           rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
            /*@=nullstate@*/
 
            /* Write the lead section into the package. */
@@ -1470,7 +1477,7 @@ psm->te->h = headerLink(fi->h);
            }
 
            /* Retrieve type of payload compression. */
-           rc = rpmpsmStage(psm, PSM_RPMIO_FLAGS);
+           rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
 
            if (rpmteFd(fi->te) == NULL) {      /* XXX can't happen */
                rc = RPMRC_FAIL;
@@ -1497,13 +1504,13 @@ psm->te->h = headerLink(fi->h);
            /*@=mods@*/
 
            if (!rc)
-               rc = rpmpsmStage(psm, PSM_COMMIT);
+               rc = rpmpsmNext(psm, PSM_COMMIT);
 
            /* XXX make sure progress is closed out */
            psm->what = RPMCALLBACK_INST_PROGRESS;
            psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
            psm->total = psm->amount;
-           xx = rpmpsmStage(psm, PSM_NOTIFY);
+           xx = rpmpsmNext(psm, PSM_NOTIFY);
 
            if (rc) {
                rpmError(RPMERR_CPIO,
@@ -1517,7 +1524,7 @@ psm->te->h = headerLink(fi->h);
                psm->what = RPMCALLBACK_UNPACK_ERROR;
                psm->amount = 0;
                psm->total = 0;
-               xx = rpmpsmStage(psm, PSM_NOTIFY);
+               xx = rpmpsmNext(psm, PSM_NOTIFY);
 
                break;
            }
@@ -1532,7 +1539,7 @@ psm->te->h = headerLink(fi->h);
            psm->what = RPMCALLBACK_UNINST_START;
            psm->amount = fc;           /* XXX W2DO? looks wrong. */
            psm->total = fc;
-           xx = rpmpsmStage(psm, PSM_NOTIFY);
+           xx = rpmpsmNext(psm, PSM_NOTIFY);
 
            rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi,
                        NULL, NULL, &psm->failedFile);
@@ -1541,7 +1548,7 @@ psm->te->h = headerLink(fi->h);
            psm->what = RPMCALLBACK_UNINST_STOP;
            psm->amount = 0;            /* XXX W2DO? looks wrong. */
            psm->total = fc;
-           xx = rpmpsmStage(psm, PSM_NOTIFY);
+           xx = rpmpsmNext(psm, PSM_NOTIFY);
 
        }
        if (psm->goal == PSM_PKGSAVE) {
@@ -1579,7 +1586,7 @@ psm->te->h = headerLink(fi->h);
            psm->what = RPMCALLBACK_INST_PROGRESS;
            psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
            psm->total = psm->amount;
-           xx = rpmpsmStage(psm, PSM_NOTIFY);
+           xx = rpmpsmNext(psm, PSM_NOTIFY);
 
            fi->action = action;
            fi->actions = actions;
@@ -1608,11 +1615,11 @@ psm->te->h = headerLink(fi->h);
             * the database before adding the new one.
             */
            if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) {
-               rc = rpmpsmStage(psm, PSM_RPMDB_REMOVE);
+               rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
                if (rc) break;
            }
 
-           rc = rpmpsmStage(psm, PSM_RPMDB_ADD);
+           rc = rpmpsmNext(psm, PSM_RPMDB_ADD);
            if (rc) break;
 
            psm->scriptTag = RPMTAG_POSTIN;
@@ -1621,16 +1628,16 @@ psm->te->h = headerLink(fi->h);
            psm->countCorrection = 0;
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
-               rc = rpmpsmStage(psm, PSM_SCRIPT);
+               rc = rpmpsmNext(psm, PSM_SCRIPT);
                if (rc) break;
            }
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
                /* Run triggers in other package(s) this package sets off. */
-               rc = rpmpsmStage(psm, PSM_TRIGGERS);
+               rc = rpmpsmNext(psm, PSM_TRIGGERS);
                if (rc) break;
 
                /* Run triggers in this package other package(s) set off. */
-               rc = rpmpsmStage(psm, PSM_IMMED_TRIGGERS);
+               rc = rpmpsmNext(psm, PSM_IMMED_TRIGGERS);
                if (rc) break;
            }
 
@@ -1646,30 +1653,30 @@ psm->te->h = headerLink(fi->h);
            psm->countCorrection = -1;
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) {
-               rc = rpmpsmStage(psm, PSM_SCRIPT);
+               rc = rpmpsmNext(psm, PSM_SCRIPT);
                /* XXX WTFO? postun failures don't cause erasure failure. */
            }
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
                /* Run triggers in other package(s) this package sets off. */
-               rc = rpmpsmStage(psm, PSM_TRIGGERS);
+               rc = rpmpsmNext(psm, PSM_TRIGGERS);
                if (rc) break;
            }
 
            if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
-               rc = rpmpsmStage(psm, PSM_RPMDB_REMOVE);
+               rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
        }
        if (psm->goal == PSM_PKGSAVE) {
        }
 
        /* Restore root directory if changed. */
-       xx = rpmpsmStage(psm, PSM_CHROOT_OUT);
+       xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
        break;
     case PSM_UNDO:
        break;
     case PSM_FINI:
        /* Restore root directory if changed. */
-       xx = rpmpsmStage(psm, PSM_CHROOT_OUT);
+       xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
 
        if (psm->fd != NULL) {
            saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
@@ -1701,7 +1708,7 @@ psm->te->h = headerLink(fi->h);
            psm->amount = 0;
            psm->total = 0;
            /*@-nullstate@*/ /* FIX: psm->fd may be NULL. */
-           xx = rpmpsmStage(psm, PSM_NOTIFY);
+           xx = rpmpsmNext(psm, PSM_NOTIFY);
            /*@=nullstate@*/
        }
 
@@ -1734,11 +1741,11 @@ psm->te->h = headerFree(psm->te->h);
        psm->rc = RPMRC_OK;
        psm->stepName = pkgStageString(stage);
 
-       rc = rpmpsmStage(psm, PSM_INIT);
-       if (!rc) rc = rpmpsmStage(psm, PSM_PRE);
-       if (!rc) rc = rpmpsmStage(psm, PSM_PROCESS);
-       if (!rc) rc = rpmpsmStage(psm, PSM_POST);
-       xx = rpmpsmStage(psm, PSM_FINI);
+       rc = rpmpsmNext(psm, PSM_INIT);
+       if (!rc) rc = rpmpsmNext(psm, PSM_PRE);
+       if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS);
+       if (!rc) rc = rpmpsmNext(psm, PSM_POST);
+       xx = rpmpsmNext(psm, PSM_FINI);
        break;
     case PSM_PKGCOMMIT:
        break;
index 2c5e502..b2c3877 100644 (file)
--- a/lib/psm.h
+++ b/lib/psm.h
@@ -99,7 +99,8 @@ struct rpmpsm_s {
     rpmRC rc;
     pkgStage goal;
 /*@unused@*/
-    pkgStage stage;
+    pkgStage stage;            /*!< Current psm stage. */
+    pkgStage nstage;           /*!< Next psm stage. */
 
 /*@refs@*/
     int nrefs;                 /*!< Reference count. */
index 15f48fe..7a04dc9 100644 (file)
@@ -62,7 +62,6 @@ rpmsq rpmsqQueue = &rpmsqRock;
 
 int rpmsqInsert(void * elem, void * prev)
 {
-    sigset_t newMask, oldMask;
     rpmsq sq = (rpmsq) elem;
     int ret = -1;
 
@@ -73,27 +72,26 @@ if (_rpmsq_debug)
 fprintf(stderr, "    Insert(%p): %p\n", ME(), sq);
 /*@=modfilesys@*/
 #endif
-       ret = sigemptyset (&newMask);
-       ret = sigaddset (&newMask, SIGCHLD);
-       ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+       ret = sighold(SIGCHLD);
        if (ret == 0) {
            sq->child = 0;
            sq->reaped = 0;
            sq->status = 0;
+           sq->reaper = 1;
+           sq->pipes[0] = sq->pipes[1] = -1;
 
            sq->id = ME();
-           (void) pthread_mutex_init(&sq->mutex, NULL);
-           (void) pthread_cond_init(&sq->cond, NULL);
+           ret = pthread_mutex_init(&sq->mutex, NULL);
+           ret = pthread_cond_init(&sq->cond, NULL);
            insque(elem, (prev ? prev : rpmsqQueue));
-           ret = sigprocmask(SIG_SETMASK, &oldMask, NULL);
+           ret = sigrelse(SIGCHLD);
        }
     }
-    return 0;
+    return ret;
 }
 
 int rpmsqRemove(void * elem)
 {
-    sigset_t newMask, oldMask;
     rpmsq sq = (rpmsq) elem;
     int ret = -1;
 
@@ -105,18 +103,20 @@ if (_rpmsq_debug)
 fprintf(stderr, "    Remove(%p): %p\n", ME(), sq);
 /*@=modfilesys@*/
 #endif
-       ret = sigemptyset (&newMask);
-       ret = sigaddset (&newMask, SIGCHLD);
-       ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
+       ret = sighold (SIGCHLD);
        if (ret == 0) {
            remque(elem);
-           (void) pthread_cond_destroy(&sq->cond);
-           (void) pthread_mutex_destroy(&sq->mutex);
+           ret = pthread_cond_destroy(&sq->cond);
+           ret = pthread_mutex_destroy(&sq->mutex);
            sq->id = NULL;
-           sq->child = 0;
-           sq->reaped = 0;
+           if (sq->pipes[1])   close(sq->pipes[1]);
+           if (sq->pipes[0])   close(sq->pipes[0]);
+           sq->pipes[0] = sq->pipes[1] = -1;
+           sq->reaper = 1;
            sq->status = 0;
-           ret = sigprocmask(SIG_SETMASK, &oldMask, NULL);
+           sq->reaped = 0;
+           sq->child = 0;
+           ret = sigrelse(SIGCHLD);
        }
     }
     return ret;
@@ -132,28 +132,28 @@ static pthread_mutex_t rpmsigTbl_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 /*@-fullinitblock@*/
 static struct rpmsig_s {
     int signum;
-    void (*handler) (int signum);
+    void (*handler) (int signum, siginfo_t * info, void * context);
     int active;
     struct sigaction oact;
 } rpmsigTbl[] = {
-    { SIGINT,  rpmsqHandler },
+    { SIGINT,  rpmsqAction },
 #define        rpmsigTbl_sigint        (&rpmsigTbl[0])
-    { SIGQUIT, rpmsqHandler },
+    { SIGQUIT, rpmsqAction },
 #define        rpmsigTbl_sigquit       (&rpmsigTbl[1])
-    { SIGCHLD, rpmsqHandler },
+    { SIGCHLD, rpmsqAction },
 #define        rpmsigTbl_sigchld       (&rpmsigTbl[2])
-    { SIGHUP,  rpmsqHandler },
+    { SIGHUP,  rpmsqAction },
 #define        rpmsigTbl_sighup        (&rpmsigTbl[3])
-    { SIGTERM, rpmsqHandler },
+    { SIGTERM, rpmsqAction },
 #define        rpmsigTbl_sigterm       (&rpmsigTbl[4])
-    { SIGPIPE, rpmsqHandler },
+    { SIGPIPE, rpmsqAction },
 #define        rpmsigTbl_sigpipe       (&rpmsigTbl[5])
     { -1,      NULL },
 };
 /*@=fullinitblock@*/
 
 /*@-incondefs@*/
-void rpmsqHandler(int signum)
+void rpmsqAction(int signum, siginfo_t * info, void * context)
 {
     int save = errno;
     rpmsig tbl;
@@ -180,33 +180,11 @@ void rpmsqHandler(int signum)
                     sq != NULL && sq != rpmsqQueue;
                     sq = sq->q_forw)
                {
-                   int same_thread;
                    if (sq->child != reaped)
                        /*@innercontinue@*/ continue;
-                   same_thread = SAME_THREAD(ME(), rpmsqQueue->id);
-#ifdef _RPMSQ_DEBUG_XXX
-/*@-modfilesys@*/
-if (_rpmsq_debug)
-fprintf(stderr, "      Reap(%p): %p child %d id %p same %d\n", ME(), sq, sq->child, sq->id, same_thread);
-/*@=modfilesys@*/
-#endif
                    sq->reaped = reaped;
                    sq->status = status;
-
-#ifdef HACK
-                   if (!SAME_THREAD(ME(), sq->id))
-#endif
-                   {
-
-#ifdef _RPMSQ_DEBUG_XXX
-/*@-modfilesys@*/
-if (_rpmsq_debug)
-fprintf(stderr, "    Signal(%p): %p child %d id %p\n", ME(), sq, sq->child, sq->id);
-/*@=modfilesys@*/
-#endif
-                       (void) pthread_cond_signal(&sq->cond);
-                   }
-
+                   (void) pthread_cond_signal(&sq->cond);
                    /*@innerbreak@*/ break;
                }
            }
@@ -220,7 +198,7 @@ fprintf(stderr, "    Signal(%p): %p child %d id %p\n", ME(), sq, sq->child, sq->
 }
 /*@=incondefs@*/
 
-int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
+int rpmsqEnable(int signum, /*@null@*/ rpmsqAction_t handler)
 {
     int tblsignum = (signum >= 0 ? signum : -signum);
     struct sigaction sa;
@@ -236,21 +214,24 @@ int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
 
        if (signum >= 0) {                      /* Enable. */
            if (ADD_REF(tbl) <= 0) {
-               tbl->active = 1;                /* XXX just in case */
                (void) sigdelset(&rpmsqCaught, tbl->signum);
-               sa.sa_flags = 0;
                sigemptyset (&sa.sa_mask);
-               sa.sa_handler = (handler != NULL ? handler : tbl->handler);
+               sa.sa_flags = SA_SIGINFO;
+               sa.sa_sigaction = (handler != NULL ? handler : tbl->handler);
                if (sigaction(tbl->signum, &sa, &tbl->oact) < 0) {
                    SUB_REF(tbl);
                    break;
                }
+               tbl->active = 1;                /* XXX just in case */
+               if (handler != NULL)
+                   tbl->handler = handler;
            }
        } else {                                /* Disable. */
            if (SUB_REF(tbl) <= 0) {
-               tbl->active = 0;                /* XXX just in case */
                if (sigaction(tbl->signum, &tbl->oact, NULL) < 0)
                    break;
+               tbl->active = 0;                /* XXX just in case */
+               tbl->handler = (handler != NULL ? handler : rpmsqAction);
            }
        }
        ret = tbl->active;
@@ -262,9 +243,7 @@ int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
 
 pid_t rpmsqFork(rpmsq sq)
 {
-    sigset_t newMask, oldMask;
     pid_t pid;
-    int pipes[2];
     int xx;
 
     if (sq->reaper) {
@@ -278,24 +257,24 @@ fprintf(stderr, "    Enable(%p): %p\n", ME(), sq);
        xx = rpmsqEnable(SIGCHLD, NULL);
     }
 
-    xx = pipe(pipes);
+    xx = pipe(sq->pipes);
 
-    xx = sigemptyset (&newMask);
-    xx = sigaddset (&newMask, SIGCHLD);
-    xx = sigprocmask (SIG_BLOCK, &newMask, &oldMask);
+    xx = sighold(SIGCHLD);
 
     pid = fork();
     if (pid < (pid_t) 0) {             /* fork failed.  */
-       close(pipes[0]);
-       close(pipes[1]);
+       xx = close(sq->pipes[0]);
+       xx = close(sq->pipes[1]);
+       sq->pipes[0] = sq->pipes[1] = -1;
        goto out;
     } else if (pid == (pid_t) 0) {     /* Child. */
        int yy;
 
        /* Block to permit parent to wait. */
-       close(pipes[1]);
-       xx = read(pipes[0], &yy, sizeof(yy));
-       close(pipes[0]);
+       xx = close(sq->pipes[1]);
+       xx = read(sq->pipes[0], &yy, sizeof(yy));
+       xx = close(sq->pipes[0]);
+       sq->pipes[0] = sq->pipes[1] = -1;
 
 #ifdef _RPMSQ_DEBUG
 /*@-modfilesys@*/
@@ -316,13 +295,14 @@ fprintf(stderr, "    Parent(%p): %p child %d\n", ME(), sq, sq->child);
 #endif
 
        /* Unblock child. */
-       close(pipes[0]);
-       close(pipes[1]);
+       xx = close(sq->pipes[0]);
+       xx = close(sq->pipes[1]);
+       sq->pipes[0] = sq->pipes[1] = -1;
 
     }
 
 out:
-    xx = sigprocmask (SIG_SETMASK, &oldMask, NULL);
+    xx = sigrelse(SIGCHLD);
     return sq->child;
 }
 
@@ -335,26 +315,16 @@ static int rpmsqWaitUnregister(rpmsq sq)
        /*@globals fileSystem, internalState @*/
        /*@modifies fileSystem, internalState @*/
 {
-    sigset_t newMask, oldMask;
-#ifdef HACK
-    int same_thread = SAME_THREAD(ME(), rpmsqQueue->id);
-#else
     int same_thread = 0;
-#endif
     int ret = 0;
     int xx;
 
-    if (same_thread) {
-       ret = sigemptyset (&newMask);
-       ret = sigaddset (&newMask, SIGCHLD);
-       ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
-    } else {
-    }
+    if (same_thread) ret = sighold(SIGCHLD);
 
     /*@-infloops@*/
     while (ret == 0 && sq->reaped != sq->child) {
        if (same_thread) {
-           ret = sigsuspend(&oldMask);
+           ret = sigpause(SIGCHLD);
        } else {
            ret = pthread_mutex_lock(&sq->mutex);
            ret = pthread_cond_wait(&sq->cond, &sq->mutex);
@@ -363,10 +333,7 @@ static int rpmsqWaitUnregister(rpmsq sq)
     }
     /*@=infloops@*/
 
-    if (same_thread) {
-       xx = sigprocmask(SIG_SETMASK, &oldMask, NULL);
-    } else {
-    }
+    if (same_thread) xx = sigrelse(SIGCHLD);
 
 #ifdef _RPMSQ_DEBUG
 /*@-modfilesys@*/
@@ -389,12 +356,11 @@ fprintf(stderr, "   Disable(%p): %p\n", ME(), sq);
 
 pid_t rpmsqWait(rpmsq sq)
 {
-    int same_thread = SAME_THREAD(ME(), rpmsqQueue->id);
 
 #ifdef _RPMSQ_DEBUG
 /*@-modfilesys@*/
 if (_rpmsq_debug)
-fprintf(stderr, "      Wait(%p): %p child %d reaper %d same %d\n", ME(), sq, sq->child, sq->reaper, same_thread);
+fprintf(stderr, "      Wait(%p): %p child %d reaper %d\n", ME(), sq, sq->child, sq->reaper);
 /*@=modfilesys@*/
 #endif
 
@@ -426,6 +392,19 @@ fprintf(stderr, "      Fini(%p): %p child %d status 0x%x\n", ME(), sq, sq->child
     return sq->reaped;
 }
 
+int rpmsqThread(void * (*start) (void * arg), void * arg)
+{
+    pthread_t pth;
+    int ret;
+
+    ret = pthread_create(&pth, NULL, start, arg);
+    if (ret == 0) {
+fprintf(stderr, "    Thread(%p): %p\n", ME(), pth);
+       ret = pthread_join(pth, NULL);
+    }
+    return ret;
+}
+
 /**
  * SIGCHLD cancellation handler.
  */
index 9e3960e..a149860 100644 (file)
@@ -15,6 +15,9 @@ typedef struct rpmsig_s * rpmsig;
 
 typedef struct rpmsqElem * rpmsq;
 
+typedef void (*rpmsqAction_t) (int signum, siginfo_t *info, void *context)
+       /*@*/;
+
 /*@-redecl@*/
 /*@unchecked@*/
 extern int _rpmsq_debug;
@@ -30,6 +33,7 @@ struct rpmsqElem {
     volatile pid_t reaped;     /*!< Reaped waitpid(3) return. */
     volatile int status;       /*!< Reaped waitpid(3) status. */
     int reaper;                        /*!< Register SIGCHLD handler? */
+    int pipes[2];
     void * id;                 /*!< Blocking thread id (pthread_t). */
     pthread_mutex_t mutex;
     pthread_cond_t cond;
@@ -58,17 +62,17 @@ int rpmsqRemove(/*@null@*/ void * elem)
 
 /**
  */
-void rpmsqHandler(int signum)
+void rpmsqAction(int signum, siginfo_t * info, void * context)
        /*@globals rpmsqCaught, fileSystem @*/
        /*@modifies rpmsqCaught, fileSystem @*/;
 
 /**
  * Enable or disable a signal handler.
  * @param signum       signal to enable (or disable if negative)
- * @param handler      signal handler (or NULL to use rpmsqHandler())
+ * @param handler      sa_sigaction handler (or NULL to use rpmsqHandler())
  * @return             no. of refs, -1 on error
  */
-int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
+int rpmsqEnable(int signum, /*@null@*/ rpmsqAction_t handler)
        /*@globals rpmsqCaught, fileSystem, internalState @*/
        /*@modifies rpmsqCaught, fileSystem, internalState @*/;
 
@@ -91,6 +95,16 @@ pid_t rpmsqWait(rpmsq sq)
        /*@modifies sq, fileSystem, internalState @*/;
 
 /**
+ * Call a function in a thread synchronously.
+ * @param start                function
+ * @param arg          function argument
+ * @return             0 on success
+ */
+int rpmsqThread(void * (*start) (void * arg), void * arg)
+       /*@globals fileSystem, internalState @*/
+       /*@modifies fileSystem, internalState @*/;
+
+/**
  * Execute a command, returning its status.
  */
 int rpmsqExecve (const char ** argv)