diff options
-rw-r--r-- | lib/cpio.c | 12 | ||||
-rw-r--r-- | lib/fsm.c | 169 | ||||
-rw-r--r-- | lib/fsm.h | 6 | ||||
-rw-r--r-- | lib/poptALL.c | 5 | ||||
-rw-r--r-- | lib/psm.c | 81 | ||||
-rw-r--r-- | lib/psm.h | 3 | ||||
-rw-r--r-- | rpmio/rpmsq.c | 149 | ||||
-rw-r--r-- | rpmio/rpmsq.h | 20 |
8 files changed, 236 insertions, 209 deletions
diff --git a/lib/cpio.c b/lib/cpio.c index 13b34b288..c72c5361d 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -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) { @@ -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; } @@ -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 diff --git a/lib/poptALL.c b/lib/poptALL.c index 174861299..94b3a404d 100644 --- a/lib/poptALL.c +++ b/lib/poptALL.c @@ -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, @@ -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; @@ -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. */ diff --git a/rpmio/rpmsq.c b/rpmio/rpmsq.c index 15f48fec8..7a04dc98a 100644 --- a/rpmio/rpmsq.c +++ b/rpmio/rpmsq.c @@ -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. */ diff --git a/rpmio/rpmsq.h b/rpmio/rpmsq.h index 9e3960ebc..a1498602a 100644 --- a/rpmio/rpmsq.h +++ b/rpmio/rpmsq.h @@ -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) |