summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/cpio.c12
-rw-r--r--lib/fsm.c169
-rw-r--r--lib/fsm.h6
-rw-r--r--lib/poptALL.c5
-rw-r--r--lib/psm.c81
-rw-r--r--lib/psm.h3
-rw-r--r--rpmio/rpmsq.c149
-rw-r--r--rpmio/rpmsq.h20
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) {
diff --git a/lib/fsm.c b/lib/fsm.c
index 94165dfa0..b6461b107 100644
--- 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;
}
diff --git a/lib/fsm.h b/lib/fsm.h
index 9ca5c8786..7a36c8a8d 100644
--- 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
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,
diff --git a/lib/psm.c b/lib/psm.c
index 5e5979daf..8e522c773 100644
--- 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;
diff --git a/lib/psm.h b/lib/psm.h
index 2c5e502c4..b2c387764 100644
--- 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. */
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)