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. */
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) {

169
lib/fsm.c
View File

@ -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;
}

View File

@ -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

View File

@ -55,6 +55,9 @@ extern int _rpmfi_debug;
/*@unchecked@*/
extern int _rpmps_debug;
/*@unchecked@*/
extern int _rpmsq_debug;
/*@unchecked@*/
extern int _rpmte_debug;
@ -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,

View File

@ -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;

View File

@ -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. */

View File

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

View File

@ -15,6 +15,9 @@ typedef struct rpmsig_s * rpmsig;
typedef struct rpmsqElem * rpmsq;
typedef void (*rpmsqAction_t) (int signum, siginfo_t *info, void *context)
/*@*/;
/*@-redecl@*/
/*@unchecked@*/
extern int _rpmsq_debug;
@ -30,6 +33,7 @@ struct rpmsqElem {
volatile pid_t reaped; /*!< Reaped waitpid(3) return. */
volatile int status; /*!< Reaped waitpid(3) status. */
int reaper; /*!< Register SIGCHLD handler? */
int pipes[2];
void * id; /*!< Blocking thread id (pthread_t). */
pthread_mutex_t mutex;
pthread_cond_t cond;
@ -58,17 +62,17 @@ int rpmsqRemove(/*@null@*/ void * elem)
/**
*/
void rpmsqHandler(int signum)
void rpmsqAction(int signum, siginfo_t * info, void * context)
/*@globals rpmsqCaught, fileSystem @*/
/*@modifies rpmsqCaught, fileSystem @*/;
/**
* Enable or disable a signal handler.
* @param signum signal to enable (or disable if negative)
* @param handler signal handler (or NULL to use rpmsqHandler())
* @param handler sa_sigaction handler (or NULL to use rpmsqHandler())
* @return no. of refs, -1 on error
*/
int rpmsqEnable(int signum, /*@null@*/ sighandler_t handler)
int rpmsqEnable(int signum, /*@null@*/ rpmsqAction_t handler)
/*@globals rpmsqCaught, fileSystem, internalState @*/
/*@modifies rpmsqCaught, fileSystem, internalState @*/;
@ -90,6 +94,16 @@ pid_t rpmsqWait(rpmsq sq)
/*@globals 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.
*/