CVS patchset: 6705
CVS date: 2003/03/19 03:00:02
This commit is contained in:
jbj 2003-03-19 03:00:02 +00:00
parent d2a425e015
commit 6cb657b9d2
8 changed files with 236 additions and 209 deletions

View File

@ -77,14 +77,14 @@ int cpioTrailerWrite(FSM_t fsm)
/* XXX DWRITE uses rdnb for I/O length. */ /* XXX DWRITE uses rdnb for I/O length. */
fsm->rdnb = PHYS_HDR_SIZE + sizeof(CPIO_TRAILER); 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 * GNU cpio pads to 512 bytes here, but we don't. This may matter for
* tape device(s) and/or concatenated cpio archives. <shrug> * tape device(s) and/or concatenated cpio archives. <shrug>
*/ */
if (!rc) if (!rc)
rc = fsmStage(fsm, FSM_PAD); rc = fsmNext(fsm, FSM_PAD);
return rc; return rc;
} }
@ -119,11 +119,11 @@ int cpioHeaderWrite(FSM_t fsm, struct stat * st)
/* XXX DWRITE uses rdnb for I/O length. */ /* XXX DWRITE uses rdnb for I/O length. */
fsm->rdnb = PHYS_HDR_SIZE + len; fsm->rdnb = PHYS_HDR_SIZE + len;
rc = fsmStage(fsm, FSM_DWRITE); rc = fsmNext(fsm, FSM_DWRITE);
if (!rc && fsm->rdnb != fsm->wrnb) if (!rc && fsm->rdnb != fsm->wrnb)
rc = CPIOERR_WRITE_FAILED; rc = CPIOERR_WRITE_FAILED;
if (!rc) if (!rc)
rc = fsmStage(fsm, FSM_PAD); rc = fsmNext(fsm, FSM_PAD);
return rc; return rc;
} }
@ -137,7 +137,7 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st)
int rc = 0; int rc = 0;
fsm->wrlen = PHYS_HDR_SIZE; fsm->wrlen = PHYS_HDR_SIZE;
rc = fsmStage(fsm, FSM_DREAD); rc = fsmNext(fsm, FSM_DREAD);
if (!rc && fsm->rdnb != fsm->wrlen) if (!rc && fsm->rdnb != fsm->wrlen)
rc = CPIOERR_READ_FAILED; rc = CPIOERR_READ_FAILED;
if (rc) return rc; if (rc) return rc;
@ -175,7 +175,7 @@ int cpioHeaderRead(FSM_t fsm, struct stat * st)
{ char * t = xmalloc(nameSize + 1); { char * t = xmalloc(nameSize + 1);
fsm->wrlen = nameSize; fsm->wrlen = nameSize;
rc = fsmStage(fsm, FSM_DREAD); rc = fsmNext(fsm, FSM_DREAD);
if (!rc && fsm->rdnb != fsm->wrlen) if (!rc && fsm->rdnb != fsm->wrlen)
rc = CPIOERR_BAD_HEADER; rc = CPIOERR_BAD_HEADER;
if (rc) { if (rc) {

169
lib/fsm.c
View File

@ -16,6 +16,7 @@
#include "rpmfi.h" #include "rpmfi.h"
#include "rpmte.h" #include "rpmte.h"
#include "rpmts.h" #include "rpmts.h"
#include "rpmsq.h"
#include "debug.h" #include "debug.h"
@ -378,6 +379,20 @@ static /*@observer@*/ const char * dnlNextIterator(/*@null@*/ DNLI_t dnli)
} }
/*@=boundsread@*/ /*@=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 /** \ingroup payload
* Save hard link in chain. * Save hard link in chain.
* @param fsm file state machine data * @param fsm file state machine data
@ -469,7 +484,7 @@ static int saveHardLink(/*@special@*/ /*@partial@*/ FSM_t fsm)
fsm->li->linkIndex = j; fsm->li->linkIndex = j;
fsm->path = _free(fsm->path); fsm->path = _free(fsm->path);
fsm->ix = ix; fsm->ix = ix;
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
return rc; return rc;
} }
/*@=boundsread@*/ /*@=boundsread@*/
@ -749,7 +764,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
int left = st->st_size; int left = st->st_size;
int rc = 0; int rc = 0;
rc = fsmStage(fsm, FSM_WOPEN); rc = fsmNext(fsm, FSM_WOPEN);
if (rc) if (rc)
goto exit; goto exit;
@ -759,11 +774,11 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
while (left) { while (left) {
fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left); fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
rc = fsmStage(fsm, FSM_DREAD); rc = fsmNext(fsm, FSM_DREAD);
if (rc) if (rc)
goto exit; goto exit;
rc = fsmStage(fsm, FSM_WRITE); rc = fsmNext(fsm, FSM_WRITE);
if (rc) if (rc)
goto exit; goto exit;
@ -771,7 +786,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
/* don't call this with fileSize == fileComplete */ /* don't call this with fileSize == fileComplete */
if (!rc && left) if (!rc && left)
(void) fsmStage(fsm, FSM_NOTIFY); (void) fsmNext(fsm, FSM_NOTIFY);
} }
if (st->st_size > 0 && (fsm->fmd5sum || fsm->md5sum)) { if (st->st_size > 0 && (fsm->fmd5sum || fsm->md5sum)) {
@ -797,7 +812,7 @@ static int expandRegular(/*@special@*/ FSM_t fsm)
} }
exit: exit:
(void) fsmStage(fsm, FSM_WCLOSE); (void) fsmNext(fsm, FSM_WCLOSE);
return rc; 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]); (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; fsm->path = path;
if (rc) goto exit; if (rc) goto exit;
@ -868,7 +883,7 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
size_t nmapped; size_t nmapped;
#endif #endif
rc = fsmStage(fsm, FSM_ROPEN); rc = fsmNext(fsm, FSM_ROPEN);
if (rc) goto exit; if (rc) goto exit;
/* XXX unbuffered mmap generates *lots* of fdio debugging */ /* XXX unbuffered mmap generates *lots* of fdio debugging */
@ -895,12 +910,12 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
#endif #endif
{ {
fsm->rdlen = (left > fsm->rdsize ? fsm->rdsize : left), fsm->rdlen = (left > fsm->rdsize ? fsm->rdsize : left),
rc = fsmStage(fsm, FSM_READ); rc = fsmNext(fsm, FSM_READ);
if (rc) goto exit; if (rc) goto exit;
} }
/* XXX DWRITE uses rdnb for I/O length. */ /* XXX DWRITE uses rdnb for I/O length. */
rc = fsmStage(fsm, FSM_DWRITE); rc = fsmNext(fsm, FSM_DWRITE);
if (rc) goto exit; if (rc) goto exit;
left -= fsm->wrnb; left -= fsm->wrnb;
@ -923,18 +938,18 @@ static int writeFile(/*@special@*/ FSM_t fsm, int writeData)
strcpy(fsm->rdbuf, symbuf); /* XXX restore readlink buffer. */ strcpy(fsm->rdbuf, symbuf); /* XXX restore readlink buffer. */
/*@=boundswrite@*/ /*@=boundswrite@*/
fsm->rdnb = strlen(symbuf); fsm->rdnb = strlen(symbuf);
rc = fsmStage(fsm, FSM_DWRITE); rc = fsmNext(fsm, FSM_DWRITE);
if (rc) goto exit; if (rc) goto exit;
} }
rc = fsmStage(fsm, FSM_PAD); rc = fsmNext(fsm, FSM_PAD);
if (rc) goto exit; if (rc) goto exit;
rc = 0; rc = 0;
exit: exit:
if (fsm->rfd != NULL) if (fsm->rfd != NULL)
(void) fsmStage(fsm, FSM_RCLOSE); (void) fsmNext(fsm, FSM_RCLOSE);
/*@-dependenttrans@*/ /*@-dependenttrans@*/
fsm->opath = opath; fsm->opath = opath;
fsm->path = path; fsm->path = path;
@ -969,7 +984,7 @@ static int writeLinkedFile(/*@special@*/ FSM_t fsm)
if (fsm->li->filex[i] < 0) continue; if (fsm->li->filex[i] < 0) continue;
fsm->ix = fsm->li->filex[i]; fsm->ix = fsm->li->filex[i];
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
/* Write data after last link. */ /* Write data after last link. */
rc = writeFile(fsm, (i == 0)); rc = writeFile(fsm, (i == 0));
@ -1014,7 +1029,7 @@ static int fsmMakeLinks(/*@special@*/ FSM_t fsm)
fsm->ix = -1; fsm->ix = -1;
fsm->ix = fsm->li->filex[fsm->li->createdPath]; fsm->ix = fsm->li->filex[fsm->li->createdPath];
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
fsm->opath = fsm->path; fsm->opath = fsm->path;
fsm->path = NULL; fsm->path = NULL;
/*@-branchstate@*/ /*@-branchstate@*/
@ -1024,15 +1039,15 @@ static int fsmMakeLinks(/*@special@*/ FSM_t fsm)
fsm->ix = fsm->li->filex[i]; fsm->ix = fsm->li->filex[i];
fsm->path = _free(fsm->path); fsm->path = _free(fsm->path);
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
if (XFA_SKIPPING(fsm->action)) continue; if (XFA_SKIPPING(fsm->action)) continue;
rc = fsmStage(fsm, FSM_VERIFY); rc = fsmUNSAFE(fsm, FSM_VERIFY);
if (!rc) continue; if (!rc) continue;
if (rc != CPIOERR_LSTAT_FAILED) break; if (rc != CPIOERR_LSTAT_FAILED) break;
/* XXX link(fsm->opath, fsm->path) */ /* XXX link(fsm->opath, fsm->path) */
rc = fsmStage(fsm, FSM_LINK); rc = fsmNext(fsm, FSM_LINK);
if (fsm->failedFile && rc != 0 && *fsm->failedFile == NULL) { if (fsm->failedFile && rc != 0 && *fsm->failedFile == NULL) {
ec = rc; ec = rc;
/*@-boundswrite@*/ /*@-boundswrite@*/
@ -1087,9 +1102,9 @@ static int fsmCommitLinks(/*@special@*/ FSM_t fsm)
for (i = 0; i < fsm->li->nlink; i++) { for (i = 0; i < fsm->li->nlink; i++) {
if (fsm->li->filex[i] < 0) continue; if (fsm->li->filex[i] < 0) continue;
fsm->ix = fsm->li->filex[i]; fsm->ix = fsm->li->filex[i];
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
if (!XFA_SKIPPING(fsm->action)) if (!XFA_SKIPPING(fsm->action))
rc = fsmStage(fsm, FSM_COMMIT); rc = fsmNext(fsm, FSM_COMMIT);
fsm->path = _free(fsm->path); fsm->path = _free(fsm->path);
fsm->li->filex[i] = -1; fsm->li->filex[i] = -1;
} }
@ -1139,7 +1154,7 @@ static int fsmRmdirs(/*@special@*/ FSM_t fsm)
do { do {
if (*te == '/') { if (*te == '/') {
*te = '\0'; *te = '\0';
rc = fsmStage(fsm, FSM_RMDIR); rc = fsmNext(fsm, FSM_RMDIR);
*te = '/'; *te = '/';
} }
if (rc) if (rc)
@ -1236,7 +1251,7 @@ static int fsmMkdirs(/*@special@*/ FSM_t fsm)
rpmfi fi = fsmGetFi(fsm); rpmfi fi = fsmGetFi(fsm);
*te = '\0'; *te = '\0';
st->st_mode = S_IFDIR | (fi->dperms & 07777); st->st_mode = S_IFDIR | (fi->dperms & 07777);
rc = fsmStage(fsm, FSM_MKDIR); rc = fsmNext(fsm, FSM_MKDIR);
if (!rc) if (!rc)
rpmMessage(RPMMESS_DEBUG, rpmMessage(RPMMESS_DEBUG,
_("%s directory created with perms %04o.\n"), _("%s directory created with perms %04o.\n"),
@ -1359,7 +1374,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
case FSM_PKGINSTALL: case FSM_PKGINSTALL:
while (1) { while (1) {
/* Clean fsm, free'ing memory. Read next archive header. */ /* Clean fsm, free'ing memory. Read next archive header. */
rc = fsmStage(fsm, FSM_INIT); rc = fsmUNSAFE(fsm, FSM_INIT);
/* Exit on end-of-payload. */ /* Exit on end-of-payload. */
if (rc == CPIOERR_HDR_TRAILER) { if (rc == CPIOERR_HDR_TRAILER) {
@ -1370,21 +1385,21 @@ int fsmStage(FSM_t fsm, fileStage stage)
/* Exit on error. */ /* Exit on error. */
if (rc) { if (rc) {
fsm->postpone = 1; fsm->postpone = 1;
(void) fsmStage(fsm, FSM_UNDO); (void) fsmNext(fsm, FSM_UNDO);
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
/* Extract file from archive. */ /* Extract file from archive. */
rc = fsmStage(fsm, FSM_PROCESS); rc = fsmNext(fsm, FSM_PROCESS);
if (rc) { if (rc) {
(void) fsmStage(fsm, FSM_UNDO); (void) fsmNext(fsm, FSM_UNDO);
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
/* Notify on success. */ /* 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) { if (rc) {
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
@ -1394,7 +1409,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
case FSM_PKGCOMMIT: case FSM_PKGCOMMIT:
while (1) { while (1) {
/* Clean fsm, free'ing memory. */ /* Clean fsm, free'ing memory. */
rc = fsmStage(fsm, FSM_INIT); rc = fsmUNSAFE(fsm, FSM_INIT);
/* Exit on end-of-payload. */ /* Exit on end-of-payload. */
if (rc == CPIOERR_HDR_TRAILER) { if (rc == CPIOERR_HDR_TRAILER) {
@ -1403,14 +1418,14 @@ int fsmStage(FSM_t fsm, fileStage stage)
} }
/* Rename/erase next item. */ /* Rename/erase next item. */
if (fsmStage(fsm, FSM_FINI)) if (fsmNext(fsm, FSM_FINI))
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
break; break;
case FSM_PKGBUILD: case FSM_PKGBUILD:
while (1) { while (1) {
rc = fsmStage(fsm, FSM_INIT); rc = fsmUNSAFE(fsm, FSM_INIT);
/* Exit on end-of-payload. */ /* Exit on end-of-payload. */
if (rc == CPIOERR_HDR_TRAILER) { if (rc == CPIOERR_HDR_TRAILER) {
@ -1421,21 +1436,21 @@ int fsmStage(FSM_t fsm, fileStage stage)
/* Exit on error. */ /* Exit on error. */
if (rc) { if (rc) {
fsm->postpone = 1; fsm->postpone = 1;
(void) fsmStage(fsm, FSM_UNDO); (void) fsmNext(fsm, FSM_UNDO);
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
/* Copy file into archive. */ /* Copy file into archive. */
rc = fsmStage(fsm, FSM_PROCESS); rc = fsmNext(fsm, FSM_PROCESS);
if (rc) { if (rc) {
(void) fsmStage(fsm, FSM_UNDO); (void) fsmNext(fsm, FSM_UNDO);
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
/* Notify on success. */ /* 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; /*@loopbreak@*/ break;
} }
@ -1472,7 +1487,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
} }
if (!rc) if (!rc)
rc = fsmStage(fsm, FSM_TRAILER); rc = fsmNext(fsm, FSM_TRAILER);
break; break;
case FSM_CREATE: case FSM_CREATE:
@ -1507,7 +1522,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
/* Detect and create directories not explicitly in package. */ /* Detect and create directories not explicitly in package. */
if (fsm->goal == FSM_PKGINSTALL) { if (fsm->goal == FSM_PKGINSTALL) {
rc = fsmStage(fsm, FSM_MKDIRS); rc = fsmNext(fsm, FSM_MKDIRS);
if (!rc) fsm->mkdirsdone = 1; if (!rc) fsm->mkdirsdone = 1;
} }
@ -1524,7 +1539,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
if (fsm->goal == FSM_PKGINSTALL) { if (fsm->goal == FSM_PKGINSTALL) {
/* Read next header from payload, checking for end-of-payload. */ /* Read next header from payload, checking for end-of-payload. */
rc = fsmStage(fsm, FSM_NEXT); rc = fsmUNSAFE(fsm, FSM_NEXT);
} }
if (rc) break; if (rc) break;
@ -1558,7 +1573,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
} }
/* Generate file path. */ /* Generate file path. */
rc = fsmStage(fsm, FSM_MAP); rc = fsmNext(fsm, FSM_MAP);
if (rc) break; if (rc) break;
/* Perform lstat/stat for disk file. */ /* Perform lstat/stat for disk file. */
@ -1618,7 +1633,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
case FSM_PROCESS: case FSM_PROCESS:
if (fsm->postpone) { if (fsm->postpone) {
if (fsm->goal == FSM_PKGINSTALL) if (fsm->goal == FSM_PKGINSTALL)
rc = fsmStage(fsm, FSM_EAT); rc = fsmNext(fsm, FSM_EAT);
break; break;
} }
@ -1655,13 +1670,13 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
const char * path = fsm->path; const char * path = fsm->path;
if (fsm->osuffix) if (fsm->osuffix)
fsm->path = fsmFsPath(fsm, st, NULL, NULL); fsm->path = fsmFsPath(fsm, st, NULL, NULL);
rc = fsmStage(fsm, FSM_VERIFY); rc = fsmUNSAFE(fsm, FSM_VERIFY);
if (rc == 0 && fsm->osuffix) { if (rc == 0 && fsm->osuffix) {
const char * opath = fsm->opath; const char * opath = fsm->opath;
fsm->opath = fsm->path; fsm->opath = fsm->path;
fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix); fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix);
rc = fsmStage(fsm, FSM_RENAME); rc = fsmNext(fsm, FSM_RENAME);
if (!rc) if (!rc)
rpmMessage(RPMMESS_WARNING, rpmMessage(RPMMESS_WARNING,
_("%s saved as %s\n"), fsm->opath, fsm->path); _("%s saved as %s\n"), fsm->opath, fsm->path);
@ -1676,11 +1691,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
rc = expandRegular(fsm); rc = expandRegular(fsm);
} else if (S_ISDIR(st->st_mode)) { } else if (S_ISDIR(st->st_mode)) {
mode_t st_mode = 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) { if (rc == CPIOERR_LSTAT_FAILED) {
st->st_mode &= ~07777; /* XXX abuse st->st_mode */ st->st_mode &= ~07777; /* XXX abuse st->st_mode */
st->st_mode |= 00700; st->st_mode |= 00700;
rc = fsmStage(fsm, FSM_MKDIR); rc = fsmNext(fsm, FSM_MKDIR);
st->st_mode = st_mode; /* XXX restore st->st_mode */ st->st_mode = st_mode; /* XXX restore st->st_mode */
} }
} else if (S_ISLNK(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; fsm->wrlen = st->st_size;
rc = fsmStage(fsm, FSM_DREAD); rc = fsmNext(fsm, FSM_DREAD);
if (!rc && fsm->rdnb != fsm->wrlen) if (!rc && fsm->rdnb != fsm->wrlen)
rc = CPIOERR_READ_FAILED; rc = CPIOERR_READ_FAILED;
if (rc) break; if (rc) break;
@ -1704,26 +1719,26 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
/*@-dependenttrans@*/ /*@-dependenttrans@*/
fsm->opath = fsm->wrbuf; fsm->opath = fsm->wrbuf;
/*@=dependenttrans@*/ /*@=dependenttrans@*/
rc = fsmStage(fsm, FSM_VERIFY); rc = fsmUNSAFE(fsm, FSM_VERIFY);
if (rc == CPIOERR_LSTAT_FAILED) if (rc == CPIOERR_LSTAT_FAILED)
rc = fsmStage(fsm, FSM_SYMLINK); rc = fsmNext(fsm, FSM_SYMLINK);
fsm->opath = opath; /* XXX restore fsm->path */ fsm->opath = opath; /* XXX restore fsm->path */
} else if (S_ISFIFO(st->st_mode)) { } else if (S_ISFIFO(st->st_mode)) {
mode_t st_mode = st->st_mode; mode_t st_mode = st->st_mode;
/* This mimics cpio S_ISSOCK() behavior but probably isnt' right */ /* 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) { if (rc == CPIOERR_LSTAT_FAILED) {
st->st_mode = 0000; /* XXX abuse st->st_mode */ 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 */ st->st_mode = st_mode; /* XXX restore st->st_mode */
} }
} else if (S_ISCHR(st->st_mode) || } else if (S_ISCHR(st->st_mode) ||
S_ISBLK(st->st_mode) || S_ISBLK(st->st_mode) ||
/*@-unrecog@*/ S_ISSOCK(st->st_mode) /*@=unrecog@*/) /*@-unrecog@*/ S_ISSOCK(st->st_mode) /*@=unrecog@*/)
{ {
rc = fsmStage(fsm, FSM_VERIFY); rc = fsmUNSAFE(fsm, FSM_VERIFY);
if (rc == CPIOERR_LSTAT_FAILED) if (rc == CPIOERR_LSTAT_FAILED)
rc = fsmStage(fsm, FSM_MKNOD); rc = fsmNext(fsm, FSM_MKNOD);
} else { } else {
/* XXX Special case /dev/log, which shouldn't be packaged anyways */ /* XXX Special case /dev/log, which shouldn't be packaged anyways */
if (!IS_DEV_LOG(fsm->path)) if (!IS_DEV_LOG(fsm->path))
@ -1756,12 +1771,12 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
if (fsm->postpone) if (fsm->postpone)
break; break;
if (fsm->goal == FSM_PKGINSTALL) { if (fsm->goal == FSM_PKGINSTALL) {
(void) fsmStage(fsm, (void) fsmNext(fsm,
(S_ISDIR(st->st_mode) ? FSM_RMDIR : FSM_UNLINK)); (S_ISDIR(st->st_mode) ? FSM_RMDIR : FSM_UNLINK));
#ifdef NOTYET /* XXX remove only dirs just created, not all. */ #ifdef NOTYET /* XXX remove only dirs just created, not all. */
if (fsm->dnlx) if (fsm->dnlx)
(void) fsmStage(fsm, FSM_RMDIRS); (void) fsmNext(fsm, FSM_RMDIRS);
#endif #endif
errno = saveerrno; errno = saveerrno;
} }
@ -1774,11 +1789,11 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
if (!fsm->postpone && fsm->commit) { if (!fsm->postpone && fsm->commit) {
if (fsm->goal == FSM_PKGINSTALL) if (fsm->goal == FSM_PKGINSTALL)
rc = ((!S_ISDIR(st->st_mode) && st->st_nlink > 1) 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) if (fsm->goal == FSM_PKGCOMMIT)
rc = fsmStage(fsm, FSM_COMMIT); rc = fsmNext(fsm, FSM_COMMIT);
if (fsm->goal == FSM_PKGERASE) if (fsm->goal == FSM_PKGERASE)
rc = fsmStage(fsm, FSM_COMMIT); rc = fsmNext(fsm, FSM_COMMIT);
} }
fsm->path = _free(fsm->path); fsm->path = _free(fsm->path);
fsm->opath = _free(fsm->opath); fsm->opath = _free(fsm->opath);
@ -1796,7 +1811,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
const char * path = fsm->path; const char * path = fsm->path;
fsm->opath = fsmFsPath(fsm, st, NULL, NULL); fsm->opath = fsmFsPath(fsm, st, NULL, NULL);
fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix); fsm->path = fsmFsPath(fsm, st, NULL, fsm->osuffix);
rc = fsmStage(fsm, FSM_RENAME); rc = fsmNext(fsm, FSM_RENAME);
if (!rc) { if (!rc) {
rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"), rpmMessage(RPMMESS_WARNING, _("%s saved as %s\n"),
fsm->opath, fsm->path); fsm->opath, fsm->path);
@ -1812,7 +1827,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
if (fsm->action == FA_ERASE) { if (fsm->action == FA_ERASE) {
rpmfi fi = fsmGetFi(fsm); rpmfi fi = fsmGetFi(fsm);
if (S_ISDIR(st->st_mode)) { if (S_ISDIR(st->st_mode)) {
rc = fsmStage(fsm, FSM_RMDIR); rc = fsmNext(fsm, FSM_RMDIR);
if (!rc) break; if (!rc) break;
switch (errno) { switch (errno) {
case ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */ case ENOENT: /* XXX rmdir("/") linux 2.2.x kernel hack */
@ -1835,7 +1850,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
/*@innerbreak@*/ break; /*@innerbreak@*/ break;
} }
} else { } else {
rc = fsmStage(fsm, FSM_UNLINK); rc = fsmNext(fsm, FSM_UNLINK);
if (!rc) break; if (!rc) break;
if (!(errno == ENOENT && (fsm->fflags & RPMFILE_MISSINGOK))) if (!(errno == ENOENT && (fsm->fflags & RPMFILE_MISSINGOK)))
rpmError( rpmError(
@ -1857,7 +1872,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
{ {
fsm->opath = fsm->path; fsm->opath = fsm->path;
fsm->path = fsmFsPath(fsm, st, NULL, fsm->nsuffix); fsm->path = fsmFsPath(fsm, st, NULL, fsm->nsuffix);
rc = fsmStage(fsm, FSM_RENAME); rc = fsmNext(fsm, FSM_RENAME);
if (!rc && fsm->nsuffix) { if (!rc && fsm->nsuffix) {
const char * opath = fsmFsPath(fsm, st, NULL, NULL); const char * opath = fsmFsPath(fsm, st, NULL, NULL);
rpmMessage(RPMMESS_WARNING, _("%s created as %s\n"), 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 (S_ISLNK(st->st_mode)) {
if (!rc && !getuid()) if (!rc && !getuid())
rc = fsmStage(fsm, FSM_LCHOWN); rc = fsmNext(fsm, FSM_LCHOWN);
} else { } else {
if (!rc && !getuid()) if (!rc && !getuid())
rc = fsmStage(fsm, FSM_CHOWN); rc = fsmNext(fsm, FSM_CHOWN);
if (!rc) if (!rc)
rc = fsmStage(fsm, FSM_CHMOD); rc = fsmNext(fsm, FSM_CHMOD);
if (!rc) { if (!rc) {
time_t mtime = st->st_mtime; time_t mtime = st->st_mtime;
rpmfi fi = fsmGetFi(fsm); rpmfi fi = fsmGetFi(fsm);
if (fi->fmtimes) if (fi->fmtimes)
st->st_mtime = fi->fmtimes[fsm->ix]; st->st_mtime = fi->fmtimes[fsm->ix];
rc = fsmStage(fsm, FSM_UTIME); rc = fsmNext(fsm, FSM_UTIME);
st->st_mtime = mtime; st->st_mtime = mtime;
} }
} }
} }
/* Notify on success. */ /* Notify on success. */
if (!rc) rc = fsmStage(fsm, FSM_NOTIFY); if (!rc) rc = fsmNext(fsm, FSM_NOTIFY);
else if (fsm->failedFile && *fsm->failedFile == NULL) { else if (fsm->failedFile && *fsm->failedFile == NULL) {
/*@-boundswrite@*/ /*@-boundswrite@*/
*fsm->failedFile = fsm->path; *fsm->failedFile = fsm->path;
@ -1910,7 +1925,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
rc = CPIOERR_MISSING_HARDLINK; rc = CPIOERR_MISSING_HARDLINK;
if (fsm->failedFile && *fsm->failedFile == NULL) { if (fsm->failedFile && *fsm->failedFile == NULL) {
fsm->ix = fsm->li->filex[i]; fsm->ix = fsm->li->filex[i];
if (!fsmStage(fsm, FSM_MAP)) { if (!fsmNext(fsm, FSM_MAP)) {
/*@-boundswrite@*/ /*@-boundswrite@*/
*fsm->failedFile = fsm->path; *fsm->failedFile = fsm->path;
/*@=boundswrite@*/ /*@=boundswrite@*/
@ -1948,9 +1963,9 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
*/ */
fsm->opath = fsm->path; fsm->opath = fsm->path;
fsm->path = path; fsm->path = path;
rc = fsmStage(fsm, FSM_RENAME); rc = fsmNext(fsm, FSM_RENAME);
if (!rc) if (!rc)
(void) fsmStage(fsm, FSM_UNLINK); (void) fsmNext(fsm, FSM_UNLINK);
else else
rc = CPIOERR_UNLINK_FAILED; rc = CPIOERR_UNLINK_FAILED;
fsm->path = fsm->opath; fsm->path = fsm->opath;
@ -1984,7 +1999,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
} }
/* XXX shouldn't do this with commit/undo. */ /* XXX shouldn't do this with commit/undo. */
rc = 0; 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; if (rc == 0) rc = CPIOERR_LSTAT_FAILED;
return (rc ? rc : CPIOERR_LSTAT_FAILED); /* XXX HACK */ return (rc ? rc : CPIOERR_LSTAT_FAILED); /* XXX HACK */
/*@notreached@*/ break; /*@notreached@*/ break;
@ -2143,12 +2158,12 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
rc = CPIOERR_HDR_TRAILER; rc = CPIOERR_HDR_TRAILER;
} }
if (!rc) if (!rc)
rc = fsmStage(fsm, FSM_POS); rc = fsmNext(fsm, FSM_POS);
break; break;
case FSM_EAT: case FSM_EAT:
for (left = st->st_size; left > 0; left -= fsm->rdnb) { for (left = st->st_size; left > 0; left -= fsm->rdnb) {
fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left); fsm->wrlen = (left > fsm->wrsize ? fsm->wrsize : left);
rc = fsmStage(fsm, FSM_DREAD); rc = fsmNext(fsm, FSM_DREAD);
if (rc) if (rc)
/*@loopbreak@*/ break; /*@loopbreak@*/ break;
} }
@ -2157,7 +2172,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
left = (modulo - (fdGetCpioPos(fsm->cfd) % modulo)) % modulo; left = (modulo - (fdGetCpioPos(fsm->cfd) % modulo)) % modulo;
if (left) { if (left) {
fsm->wrlen = left; fsm->wrlen = left;
(void) fsmStage(fsm, FSM_DREAD); (void) fsmNext(fsm, FSM_DREAD);
} }
break; break;
case FSM_PAD: case FSM_PAD:
@ -2168,14 +2183,14 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
/*@=boundswrite@*/ /*@=boundswrite@*/
/* XXX DWRITE uses rdnb for I/O length. */ /* XXX DWRITE uses rdnb for I/O length. */
fsm->rdnb = left; fsm->rdnb = left;
(void) fsmStage(fsm, FSM_DWRITE); (void) fsmNext(fsm, FSM_DWRITE);
} }
break; break;
case FSM_TRAILER: case FSM_TRAILER:
rc = cpioTrailerWrite(fsm); rc = cpioTrailerWrite(fsm);
break; break;
case FSM_HREAD: case FSM_HREAD:
rc = fsmStage(fsm, FSM_POS); rc = fsmNext(fsm, FSM_POS);
if (!rc) if (!rc)
rc = cpioHeaderRead(fsm, st); /* Read next payload header. */ rc = cpioHeaderRead(fsm, st); /* Read next payload header. */
break; break;
@ -2210,7 +2225,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
case FSM_ROPEN: case FSM_ROPEN:
fsm->rfd = Fopen(fsm->path, "r.ufdio"); fsm->rfd = Fopen(fsm->path, "r.ufdio");
if (fsm->rfd == NULL || Ferror(fsm->rfd)) { 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; fsm->rfd = NULL;
rc = CPIOERR_OPEN_FAILED; rc = CPIOERR_OPEN_FAILED;
break; break;
@ -2241,7 +2256,7 @@ if (!(fsm->mapFlags & CPIO_ALL_HARDLINKS)) break;
case FSM_WOPEN: case FSM_WOPEN:
fsm->wfd = Fopen(fsm->path, "w.ufdio"); fsm->wfd = Fopen(fsm->path, "w.ufdio");
if (fsm->wfd == NULL || Ferror(fsm->wfd)) { 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; fsm->wfd = NULL;
rc = CPIOERR_OPEN_FAILED; rc = CPIOERR_OPEN_FAILED;
} }

View File

@ -188,6 +188,7 @@ struct fsm_s {
fileAction action; /*!< File disposition. */ fileAction action; /*!< File disposition. */
fileStage goal; /*!< Package state machine goal. */ fileStage goal; /*!< Package state machine goal. */
fileStage stage; /*!< External file stage. */ fileStage stage; /*!< External file stage. */
fileStage nstage; /*!< Next file stage. */
struct stat sb; /*!< Current file stat(2) info. */ struct stat sb; /*!< Current file stat(2) info. */
struct stat osb; /*!< Original file stat(2) info. */ struct stat osb; /*!< Original file stat(2) info. */
}; };
@ -290,6 +291,9 @@ int fsmMapAttrs(FSM_t fsm)
/*@modifies fsm @*/; /*@modifies fsm @*/;
/*@=exportlocal@*/ /*@=exportlocal@*/
int fsmNext(FSM_t fsm, fileStage nstage)
/*@modifies fsm @*/;
/** /**
* File state machine driver. * File state machine driver.
* @param fsm file state machine data * @param fsm file state machine data
@ -300,6 +304,8 @@ int fsmStage(/*@partial@*/ FSM_t fsm, fileStage stage)
/*@globals errno, fileSystem, internalState @*/ /*@globals errno, fileSystem, internalState @*/
/*@modifies fsm, errno, fileSystem, internalState @*/; /*@modifies fsm, errno, fileSystem, internalState @*/;
#define fsmUNSAFE fsmStage
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -55,6 +55,9 @@ extern int _rpmfi_debug;
/*@unchecked@*/ /*@unchecked@*/
extern int _rpmps_debug; extern int _rpmps_debug;
/*@unchecked@*/
extern int _rpmsq_debug;
/*@unchecked@*/ /*@unchecked@*/
extern int _rpmte_debug; extern int _rpmte_debug;
@ -290,6 +293,8 @@ struct poptOption rpmcliAllPoptTable[] = {
N_("debug rpmio I/O"), NULL}, N_("debug rpmio I/O"), NULL},
{ "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1, { "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1,
NULL, NULL}, 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, { "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
NULL, NULL}, NULL, NULL},
{ "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1, { "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,

View File

@ -531,9 +531,6 @@ static rpmRC runScript(rpmpsm psm, Header h, const char * sln,
if (progArgv == NULL && script == NULL) if (progArgv == NULL && script == NULL)
return rc; return rc;
psm->sq.child = 0;
psm->sq.reaped = 0;
psm->sq.status = 0;
psm->sq.reaper = 1; psm->sq.reaper = 1;
/* XXX FIXME: except for %verifyscript, rpmteNEVR can be used. */ /* 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"), rpmMessage(RPMMESS_DEBUG, _("%s: %s(%s-%s-%s)\texecv(%s) pid %d\n"),
psm->stepName, sln, n, v, r, psm->stepName, sln, n, v, r,
argv[0], (unsigned)getpid()); argv[0], (unsigned)getpid());
/*@-modfilesys@*/
if (_psm_debug)
fprintf(stderr, " Exec: %s \"%s\"\n", sln, argv[0]);
/*@=modfilesys@*/
unsetenv("MALLOC_CHECK_"); unsetenv("MALLOC_CHECK_");
xx = execv(argv[0], (char *const *)argv); xx = execv(argv[0], (char *const *)argv);
break; break;
@ -1135,6 +1128,20 @@ rpmpsm rpmpsmNew(rpmts ts, rpmte te, rpmfi fi)
return rpmpsmLink(psm, msg); 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 * @todo Packages w/o files never get a callback, hence don't get displayed
* on install with -v. * on install with -v.
@ -1241,7 +1248,7 @@ assert(psm->mi == NULL);
psm->scriptArg = psm->npkgs_installed - 1; psm->scriptArg = psm->npkgs_installed - 1;
/* Retrieve installed header. */ /* Retrieve installed header. */
rc = rpmpsmStage(psm, PSM_RPMDB_LOAD); rc = rpmpsmNext(psm, PSM_RPMDB_LOAD);
if (rc == RPMRC_OK) if (rc == RPMRC_OK)
if (psm->te) if (psm->te)
psm->te->h = headerLink(fi->h); psm->te->h = headerLink(fi->h);
@ -1281,7 +1288,7 @@ psm->te->h = headerLink(fi->h);
#endif #endif
/* Change root directory if requested and not already done. */ /* 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) { if (psm->goal == PSM_PKGINSTALL) {
psm->scriptTag = RPMTAG_PREIN; psm->scriptTag = RPMTAG_PREIN;
@ -1292,7 +1299,7 @@ psm->te->h = headerLink(fi->h);
} }
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) { if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPRE)) {
rc = rpmpsmStage(psm, PSM_SCRIPT); rc = rpmpsmNext(psm, PSM_SCRIPT);
if (rc != RPMRC_OK) { if (rc != RPMRC_OK) {
rpmError(RPMERR_SCRIPT, rpmError(RPMERR_SCRIPT,
_("%s: %s scriptlet failed (%d), skipping %s\n"), _("%s: %s scriptlet failed (%d), skipping %s\n"),
@ -1311,16 +1318,16 @@ psm->te->h = headerLink(fi->h);
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) { if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERUN)) {
/* Run triggers in this package other package(s) set off. */ /* 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; if (rc) break;
/* Run triggers in other package(s) this package sets off. */ /* Run triggers in other package(s) this package sets off. */
rc = rpmpsmStage(psm, PSM_TRIGGERS); rc = rpmpsmNext(psm, PSM_TRIGGERS);
if (rc) break; if (rc) break;
} }
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN)) if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPREUN))
rc = rpmpsmStage(psm, PSM_SCRIPT); rc = rpmpsmNext(psm, PSM_SCRIPT);
} }
if (psm->goal == PSM_PKGSAVE) { if (psm->goal == PSM_PKGSAVE) {
int noArchiveSize = 0; int noArchiveSize = 0;
@ -1366,7 +1373,7 @@ psm->te->h = headerLink(fi->h);
/* Retrieve type of payload compression. */ /* Retrieve type of payload compression. */
/*@-nullstate@*/ /* FIX: psm->oh may be NULL */ /*@-nullstate@*/ /* FIX: psm->oh may be NULL */
rc = rpmpsmStage(psm, PSM_RPMIO_FLAGS); rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
/*@=nullstate@*/ /*@=nullstate@*/
/* Write the lead section into the package. */ /* Write the lead section into the package. */
@ -1470,7 +1477,7 @@ psm->te->h = headerLink(fi->h);
} }
/* Retrieve type of payload compression. */ /* 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 */ if (rpmteFd(fi->te) == NULL) { /* XXX can't happen */
rc = RPMRC_FAIL; rc = RPMRC_FAIL;
@ -1497,13 +1504,13 @@ psm->te->h = headerLink(fi->h);
/*@=mods@*/ /*@=mods@*/
if (!rc) if (!rc)
rc = rpmpsmStage(psm, PSM_COMMIT); rc = rpmpsmNext(psm, PSM_COMMIT);
/* XXX make sure progress is closed out */ /* XXX make sure progress is closed out */
psm->what = RPMCALLBACK_INST_PROGRESS; psm->what = RPMCALLBACK_INST_PROGRESS;
psm->amount = (fi->archiveSize ? fi->archiveSize : 100); psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
psm->total = psm->amount; psm->total = psm->amount;
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
if (rc) { if (rc) {
rpmError(RPMERR_CPIO, rpmError(RPMERR_CPIO,
@ -1517,7 +1524,7 @@ psm->te->h = headerLink(fi->h);
psm->what = RPMCALLBACK_UNPACK_ERROR; psm->what = RPMCALLBACK_UNPACK_ERROR;
psm->amount = 0; psm->amount = 0;
psm->total = 0; psm->total = 0;
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
break; break;
} }
@ -1532,7 +1539,7 @@ psm->te->h = headerLink(fi->h);
psm->what = RPMCALLBACK_UNINST_START; psm->what = RPMCALLBACK_UNINST_START;
psm->amount = fc; /* XXX W2DO? looks wrong. */ psm->amount = fc; /* XXX W2DO? looks wrong. */
psm->total = fc; psm->total = fc;
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi, rc = fsmSetup(fi->fsm, FSM_PKGERASE, ts, fi,
NULL, NULL, &psm->failedFile); NULL, NULL, &psm->failedFile);
@ -1541,7 +1548,7 @@ psm->te->h = headerLink(fi->h);
psm->what = RPMCALLBACK_UNINST_STOP; psm->what = RPMCALLBACK_UNINST_STOP;
psm->amount = 0; /* XXX W2DO? looks wrong. */ psm->amount = 0; /* XXX W2DO? looks wrong. */
psm->total = fc; psm->total = fc;
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
} }
if (psm->goal == PSM_PKGSAVE) { if (psm->goal == PSM_PKGSAVE) {
@ -1579,7 +1586,7 @@ psm->te->h = headerLink(fi->h);
psm->what = RPMCALLBACK_INST_PROGRESS; psm->what = RPMCALLBACK_INST_PROGRESS;
psm->amount = (fi->archiveSize ? fi->archiveSize : 100); psm->amount = (fi->archiveSize ? fi->archiveSize : 100);
psm->total = psm->amount; psm->total = psm->amount;
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
fi->action = action; fi->action = action;
fi->actions = actions; fi->actions = actions;
@ -1608,11 +1615,11 @@ psm->te->h = headerLink(fi->h);
* the database before adding the new one. * the database before adding the new one.
*/ */
if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) { if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) {
rc = rpmpsmStage(psm, PSM_RPMDB_REMOVE); rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
if (rc) break; if (rc) break;
} }
rc = rpmpsmStage(psm, PSM_RPMDB_ADD); rc = rpmpsmNext(psm, PSM_RPMDB_ADD);
if (rc) break; if (rc) break;
psm->scriptTag = RPMTAG_POSTIN; psm->scriptTag = RPMTAG_POSTIN;
@ -1621,16 +1628,16 @@ psm->te->h = headerLink(fi->h);
psm->countCorrection = 0; psm->countCorrection = 0;
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) { if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOST)) {
rc = rpmpsmStage(psm, PSM_SCRIPT); rc = rpmpsmNext(psm, PSM_SCRIPT);
if (rc) break; if (rc) break;
} }
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) { if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERIN)) {
/* Run triggers in other package(s) this package sets off. */ /* Run triggers in other package(s) this package sets off. */
rc = rpmpsmStage(psm, PSM_TRIGGERS); rc = rpmpsmNext(psm, PSM_TRIGGERS);
if (rc) break; if (rc) break;
/* Run triggers in this package other package(s) set off. */ /* 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; if (rc) break;
} }
@ -1646,30 +1653,30 @@ psm->te->h = headerLink(fi->h);
psm->countCorrection = -1; psm->countCorrection = -1;
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOPOSTUN)) { 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. */ /* XXX WTFO? postun failures don't cause erasure failure. */
} }
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) { if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERPOSTUN)) {
/* Run triggers in other package(s) this package sets off. */ /* Run triggers in other package(s) this package sets off. */
rc = rpmpsmStage(psm, PSM_TRIGGERS); rc = rpmpsmNext(psm, PSM_TRIGGERS);
if (rc) break; if (rc) break;
} }
if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY))
rc = rpmpsmStage(psm, PSM_RPMDB_REMOVE); rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
} }
if (psm->goal == PSM_PKGSAVE) { if (psm->goal == PSM_PKGSAVE) {
} }
/* Restore root directory if changed. */ /* Restore root directory if changed. */
xx = rpmpsmStage(psm, PSM_CHROOT_OUT); xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
break; break;
case PSM_UNDO: case PSM_UNDO:
break; break;
case PSM_FINI: case PSM_FINI:
/* Restore root directory if changed. */ /* Restore root directory if changed. */
xx = rpmpsmStage(psm, PSM_CHROOT_OUT); xx = rpmpsmNext(psm, PSM_CHROOT_OUT);
if (psm->fd != NULL) { if (psm->fd != NULL) {
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */ saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
@ -1701,7 +1708,7 @@ psm->te->h = headerLink(fi->h);
psm->amount = 0; psm->amount = 0;
psm->total = 0; psm->total = 0;
/*@-nullstate@*/ /* FIX: psm->fd may be NULL. */ /*@-nullstate@*/ /* FIX: psm->fd may be NULL. */
xx = rpmpsmStage(psm, PSM_NOTIFY); xx = rpmpsmNext(psm, PSM_NOTIFY);
/*@=nullstate@*/ /*@=nullstate@*/
} }
@ -1734,11 +1741,11 @@ psm->te->h = headerFree(psm->te->h);
psm->rc = RPMRC_OK; psm->rc = RPMRC_OK;
psm->stepName = pkgStageString(stage); psm->stepName = pkgStageString(stage);
rc = rpmpsmStage(psm, PSM_INIT); rc = rpmpsmNext(psm, PSM_INIT);
if (!rc) rc = rpmpsmStage(psm, PSM_PRE); if (!rc) rc = rpmpsmNext(psm, PSM_PRE);
if (!rc) rc = rpmpsmStage(psm, PSM_PROCESS); if (!rc) rc = rpmpsmNext(psm, PSM_PROCESS);
if (!rc) rc = rpmpsmStage(psm, PSM_POST); if (!rc) rc = rpmpsmNext(psm, PSM_POST);
xx = rpmpsmStage(psm, PSM_FINI); xx = rpmpsmNext(psm, PSM_FINI);
break; break;
case PSM_PKGCOMMIT: case PSM_PKGCOMMIT:
break; break;

View File

@ -99,7 +99,8 @@ struct rpmpsm_s {
rpmRC rc; rpmRC rc;
pkgStage goal; pkgStage goal;
/*@unused@*/ /*@unused@*/
pkgStage stage; pkgStage stage; /*!< Current psm stage. */
pkgStage nstage; /*!< Next psm stage. */
/*@refs@*/ /*@refs@*/
int nrefs; /*!< Reference count. */ int nrefs; /*!< Reference count. */

View File

@ -62,7 +62,6 @@ rpmsq rpmsqQueue = &rpmsqRock;
int rpmsqInsert(void * elem, void * prev) int rpmsqInsert(void * elem, void * prev)
{ {
sigset_t newMask, oldMask;
rpmsq sq = (rpmsq) elem; rpmsq sq = (rpmsq) elem;
int ret = -1; int ret = -1;
@ -73,27 +72,26 @@ if (_rpmsq_debug)
fprintf(stderr, " Insert(%p): %p\n", ME(), sq); fprintf(stderr, " Insert(%p): %p\n", ME(), sq);
/*@=modfilesys@*/ /*@=modfilesys@*/
#endif #endif
ret = sigemptyset (&newMask); ret = sighold(SIGCHLD);
ret = sigaddset (&newMask, SIGCHLD);
ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
if (ret == 0) { if (ret == 0) {
sq->child = 0; sq->child = 0;
sq->reaped = 0; sq->reaped = 0;
sq->status = 0; sq->status = 0;
sq->reaper = 1;
sq->pipes[0] = sq->pipes[1] = -1;
sq->id = ME(); sq->id = ME();
(void) pthread_mutex_init(&sq->mutex, NULL); ret = pthread_mutex_init(&sq->mutex, NULL);
(void) pthread_cond_init(&sq->cond, NULL); ret = pthread_cond_init(&sq->cond, NULL);
insque(elem, (prev ? prev : rpmsqQueue)); insque(elem, (prev ? prev : rpmsqQueue));
ret = sigprocmask(SIG_SETMASK, &oldMask, NULL); ret = sigrelse(SIGCHLD);
} }
} }
return 0; return ret;
} }
int rpmsqRemove(void * elem) int rpmsqRemove(void * elem)
{ {
sigset_t newMask, oldMask;
rpmsq sq = (rpmsq) elem; rpmsq sq = (rpmsq) elem;
int ret = -1; int ret = -1;
@ -105,18 +103,20 @@ if (_rpmsq_debug)
fprintf(stderr, " Remove(%p): %p\n", ME(), sq); fprintf(stderr, " Remove(%p): %p\n", ME(), sq);
/*@=modfilesys@*/ /*@=modfilesys@*/
#endif #endif
ret = sigemptyset (&newMask); ret = sighold (SIGCHLD);
ret = sigaddset (&newMask, SIGCHLD);
ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
if (ret == 0) { if (ret == 0) {
remque(elem); remque(elem);
(void) pthread_cond_destroy(&sq->cond); ret = pthread_cond_destroy(&sq->cond);
(void) pthread_mutex_destroy(&sq->mutex); ret = pthread_mutex_destroy(&sq->mutex);
sq->id = NULL; sq->id = NULL;
sq->child = 0; if (sq->pipes[1]) close(sq->pipes[1]);
sq->reaped = 0; if (sq->pipes[0]) close(sq->pipes[0]);
sq->pipes[0] = sq->pipes[1] = -1;
sq->reaper = 1;
sq->status = 0; sq->status = 0;
ret = sigprocmask(SIG_SETMASK, &oldMask, NULL); sq->reaped = 0;
sq->child = 0;
ret = sigrelse(SIGCHLD);
} }
} }
return ret; return ret;
@ -132,28 +132,28 @@ static pthread_mutex_t rpmsigTbl_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
/*@-fullinitblock@*/ /*@-fullinitblock@*/
static struct rpmsig_s { static struct rpmsig_s {
int signum; int signum;
void (*handler) (int signum); void (*handler) (int signum, siginfo_t * info, void * context);
int active; int active;
struct sigaction oact; struct sigaction oact;
} rpmsigTbl[] = { } rpmsigTbl[] = {
{ SIGINT, rpmsqHandler }, { SIGINT, rpmsqAction },
#define rpmsigTbl_sigint (&rpmsigTbl[0]) #define rpmsigTbl_sigint (&rpmsigTbl[0])
{ SIGQUIT, rpmsqHandler }, { SIGQUIT, rpmsqAction },
#define rpmsigTbl_sigquit (&rpmsigTbl[1]) #define rpmsigTbl_sigquit (&rpmsigTbl[1])
{ SIGCHLD, rpmsqHandler }, { SIGCHLD, rpmsqAction },
#define rpmsigTbl_sigchld (&rpmsigTbl[2]) #define rpmsigTbl_sigchld (&rpmsigTbl[2])
{ SIGHUP, rpmsqHandler }, { SIGHUP, rpmsqAction },
#define rpmsigTbl_sighup (&rpmsigTbl[3]) #define rpmsigTbl_sighup (&rpmsigTbl[3])
{ SIGTERM, rpmsqHandler }, { SIGTERM, rpmsqAction },
#define rpmsigTbl_sigterm (&rpmsigTbl[4]) #define rpmsigTbl_sigterm (&rpmsigTbl[4])
{ SIGPIPE, rpmsqHandler }, { SIGPIPE, rpmsqAction },
#define rpmsigTbl_sigpipe (&rpmsigTbl[5]) #define rpmsigTbl_sigpipe (&rpmsigTbl[5])
{ -1, NULL }, { -1, NULL },
}; };
/*@=fullinitblock@*/ /*@=fullinitblock@*/
/*@-incondefs@*/ /*@-incondefs@*/
void rpmsqHandler(int signum) void rpmsqAction(int signum, siginfo_t * info, void * context)
{ {
int save = errno; int save = errno;
rpmsig tbl; rpmsig tbl;
@ -180,33 +180,11 @@ void rpmsqHandler(int signum)
sq != NULL && sq != rpmsqQueue; sq != NULL && sq != rpmsqQueue;
sq = sq->q_forw) sq = sq->q_forw)
{ {
int same_thread;
if (sq->child != reaped) if (sq->child != reaped)
/*@innercontinue@*/ continue; /*@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->reaped = reaped;
sq->status = status; sq->status = status;
(void) pthread_cond_signal(&sq->cond);
#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);
}
/*@innerbreak@*/ break; /*@innerbreak@*/ break;
} }
} }
@ -220,7 +198,7 @@ fprintf(stderr, " Signal(%p): %p child %d id %p\n", ME(), sq, sq->child, sq->
} }
/*@=incondefs@*/ /*@=incondefs@*/
int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler) int rpmsqEnable(int signum, /*@null@*/ rpmsqAction_t handler)
{ {
int tblsignum = (signum >= 0 ? signum : -signum); int tblsignum = (signum >= 0 ? signum : -signum);
struct sigaction sa; struct sigaction sa;
@ -236,21 +214,24 @@ int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
if (signum >= 0) { /* Enable. */ if (signum >= 0) { /* Enable. */
if (ADD_REF(tbl) <= 0) { if (ADD_REF(tbl) <= 0) {
tbl->active = 1; /* XXX just in case */
(void) sigdelset(&rpmsqCaught, tbl->signum); (void) sigdelset(&rpmsqCaught, tbl->signum);
sa.sa_flags = 0;
sigemptyset (&sa.sa_mask); 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) { if (sigaction(tbl->signum, &sa, &tbl->oact) < 0) {
SUB_REF(tbl); SUB_REF(tbl);
break; break;
} }
tbl->active = 1; /* XXX just in case */
if (handler != NULL)
tbl->handler = handler;
} }
} else { /* Disable. */ } else { /* Disable. */
if (SUB_REF(tbl) <= 0) { if (SUB_REF(tbl) <= 0) {
tbl->active = 0; /* XXX just in case */
if (sigaction(tbl->signum, &tbl->oact, NULL) < 0) if (sigaction(tbl->signum, &tbl->oact, NULL) < 0)
break; break;
tbl->active = 0; /* XXX just in case */
tbl->handler = (handler != NULL ? handler : rpmsqAction);
} }
} }
ret = tbl->active; ret = tbl->active;
@ -262,9 +243,7 @@ int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
pid_t rpmsqFork(rpmsq sq) pid_t rpmsqFork(rpmsq sq)
{ {
sigset_t newMask, oldMask;
pid_t pid; pid_t pid;
int pipes[2];
int xx; int xx;
if (sq->reaper) { if (sq->reaper) {
@ -278,24 +257,24 @@ fprintf(stderr, " Enable(%p): %p\n", ME(), sq);
xx = rpmsqEnable(SIGCHLD, NULL); xx = rpmsqEnable(SIGCHLD, NULL);
} }
xx = pipe(pipes); xx = pipe(sq->pipes);
xx = sigemptyset (&newMask); xx = sighold(SIGCHLD);
xx = sigaddset (&newMask, SIGCHLD);
xx = sigprocmask (SIG_BLOCK, &newMask, &oldMask);
pid = fork(); pid = fork();
if (pid < (pid_t) 0) { /* fork failed. */ if (pid < (pid_t) 0) { /* fork failed. */
close(pipes[0]); xx = close(sq->pipes[0]);
close(pipes[1]); xx = close(sq->pipes[1]);
sq->pipes[0] = sq->pipes[1] = -1;
goto out; goto out;
} else if (pid == (pid_t) 0) { /* Child. */ } else if (pid == (pid_t) 0) { /* Child. */
int yy; int yy;
/* Block to permit parent to wait. */ /* Block to permit parent to wait. */
close(pipes[1]); xx = close(sq->pipes[1]);
xx = read(pipes[0], &yy, sizeof(yy)); xx = read(sq->pipes[0], &yy, sizeof(yy));
close(pipes[0]); xx = close(sq->pipes[0]);
sq->pipes[0] = sq->pipes[1] = -1;
#ifdef _RPMSQ_DEBUG #ifdef _RPMSQ_DEBUG
/*@-modfilesys@*/ /*@-modfilesys@*/
@ -316,13 +295,14 @@ fprintf(stderr, " Parent(%p): %p child %d\n", ME(), sq, sq->child);
#endif #endif
/* Unblock child. */ /* Unblock child. */
close(pipes[0]); xx = close(sq->pipes[0]);
close(pipes[1]); xx = close(sq->pipes[1]);
sq->pipes[0] = sq->pipes[1] = -1;
} }
out: out:
xx = sigprocmask (SIG_SETMASK, &oldMask, NULL); xx = sigrelse(SIGCHLD);
return sq->child; return sq->child;
} }
@ -335,26 +315,16 @@ static int rpmsqWaitUnregister(rpmsq sq)
/*@globals fileSystem, internalState @*/ /*@globals fileSystem, internalState @*/
/*@modifies fileSystem, internalState @*/ /*@modifies fileSystem, internalState @*/
{ {
sigset_t newMask, oldMask;
#ifdef HACK
int same_thread = SAME_THREAD(ME(), rpmsqQueue->id);
#else
int same_thread = 0; int same_thread = 0;
#endif
int ret = 0; int ret = 0;
int xx; int xx;
if (same_thread) { if (same_thread) ret = sighold(SIGCHLD);
ret = sigemptyset (&newMask);
ret = sigaddset (&newMask, SIGCHLD);
ret = sigprocmask(SIG_BLOCK, &newMask, &oldMask);
} else {
}
/*@-infloops@*/ /*@-infloops@*/
while (ret == 0 && sq->reaped != sq->child) { while (ret == 0 && sq->reaped != sq->child) {
if (same_thread) { if (same_thread) {
ret = sigsuspend(&oldMask); ret = sigpause(SIGCHLD);
} else { } else {
ret = pthread_mutex_lock(&sq->mutex); ret = pthread_mutex_lock(&sq->mutex);
ret = pthread_cond_wait(&sq->cond, &sq->mutex); ret = pthread_cond_wait(&sq->cond, &sq->mutex);
@ -363,10 +333,7 @@ static int rpmsqWaitUnregister(rpmsq sq)
} }
/*@=infloops@*/ /*@=infloops@*/
if (same_thread) { if (same_thread) xx = sigrelse(SIGCHLD);
xx = sigprocmask(SIG_SETMASK, &oldMask, NULL);
} else {
}
#ifdef _RPMSQ_DEBUG #ifdef _RPMSQ_DEBUG
/*@-modfilesys@*/ /*@-modfilesys@*/
@ -389,12 +356,11 @@ fprintf(stderr, " Disable(%p): %p\n", ME(), sq);
pid_t rpmsqWait(rpmsq sq) pid_t rpmsqWait(rpmsq sq)
{ {
int same_thread = SAME_THREAD(ME(), rpmsqQueue->id);
#ifdef _RPMSQ_DEBUG #ifdef _RPMSQ_DEBUG
/*@-modfilesys@*/ /*@-modfilesys@*/
if (_rpmsq_debug) 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@*/ /*@=modfilesys@*/
#endif #endif
@ -426,6 +392,19 @@ fprintf(stderr, " Fini(%p): %p child %d status 0x%x\n", ME(), sq, sq->child
return sq->reaped; 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. * SIGCHLD cancellation handler.
*/ */

View File

@ -15,6 +15,9 @@ typedef struct rpmsig_s * rpmsig;
typedef struct rpmsqElem * rpmsq; typedef struct rpmsqElem * rpmsq;
typedef void (*rpmsqAction_t) (int signum, siginfo_t *info, void *context)
/*@*/;
/*@-redecl@*/ /*@-redecl@*/
/*@unchecked@*/ /*@unchecked@*/
extern int _rpmsq_debug; extern int _rpmsq_debug;
@ -30,6 +33,7 @@ struct rpmsqElem {
volatile pid_t reaped; /*!< Reaped waitpid(3) return. */ volatile pid_t reaped; /*!< Reaped waitpid(3) return. */
volatile int status; /*!< Reaped waitpid(3) status. */ volatile int status; /*!< Reaped waitpid(3) status. */
int reaper; /*!< Register SIGCHLD handler? */ int reaper; /*!< Register SIGCHLD handler? */
int pipes[2];
void * id; /*!< Blocking thread id (pthread_t). */ void * id; /*!< Blocking thread id (pthread_t). */
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; 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 @*/ /*@globals rpmsqCaught, fileSystem @*/
/*@modifies rpmsqCaught, fileSystem @*/; /*@modifies rpmsqCaught, fileSystem @*/;
/** /**
* Enable or disable a signal handler. * Enable or disable a signal handler.
* @param signum signal to enable (or disable if negative) * @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 * @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 @*/ /*@globals rpmsqCaught, fileSystem, internalState @*/
/*@modifies rpmsqCaught, fileSystem, internalState @*/; /*@modifies rpmsqCaught, fileSystem, internalState @*/;
@ -90,6 +94,16 @@ pid_t rpmsqWait(rpmsq sq)
/*@globals fileSystem, internalState @*/ /*@globals fileSystem, internalState @*/
/*@modifies sq, fileSystem, internalState @*/; /*@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. * Execute a command, returning its status.
*/ */