Rewrite rpmMkTempFile() for sanity

- Actually use mkstemp() for creating the temp file and return a FD_t
  dupped from the file descriptor returned by mkstemp().
- Simplify the interface while at it.
- Change callers for the new interface.
- Yes we now require mkstemp() to work, mkstemp() is in POSIX.1-2001 and
  this is year 2008...
This commit is contained in:
Panu Matilainen 2008-04-11 09:05:05 +03:00
parent 48ff62a529
commit fde961e25b
7 changed files with 45 additions and 100 deletions

View File

@ -126,7 +126,8 @@ rpmRC doScript(rpmSpec spec, rpmBuildFlags what, const char *name, StringBuf sb,
goto exit;
}
if (rpmMkTempFile(rootDir, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
fd = rpmMkTemp(rootDir, &scriptName);
if (fd == NULL || Ferror(fd)) {
rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
rc = RPMRC_FAIL;
goto exit;

View File

@ -407,7 +407,8 @@ rpmRC writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
* Write the header+archive into a temp file so that the size of
* archive (after compression) can be added to the header.
*/
if (rpmMkTempFile(NULL, &sigtarget, &fd)) {
fd = rpmMkTemp(NULL, &sigtarget);
if (fd == NULL || Ferror(fd)) {
rc = RPMRC_FAIL;
rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
goto exit;

View File

@ -10,7 +10,7 @@
#include <rpm/rpmurl.h>
#include <rpm/rpmds.h>
#include <rpm/rpmts.h>
#include <rpm/rpmfileutil.h> /* rpmMkTempFile() */
#include <rpm/rpmfileutil.h> /* rpmMkTemp() */
#include <rpm/rpmdb.h> /* XXX for db_chrootDone */
#include <rpm/rpmlog.h>
#include <rpm/rpmstring.h>
@ -696,7 +696,8 @@ static rpmRC runScript(rpmpsm psm, Header h, rpmTag stag,
const char * rootDir = rpmtsRootDir(ts);
FD_t fd;
if (rpmMkTempFile((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn, &fd)) {
fd = rpmMkTemp((!rpmtsChrootDone(ts) ? rootDir : "/"), &fn);
if (fd == NULL || Ferror(fd)) {
if (prefixes != NULL && freePrefixes) free(prefixes);
return RPMRC_FAIL;
}

View File

@ -8,7 +8,7 @@
#include <rpm/rpmlib.h> /* RPMSIGTAG & related */
#include <rpm/rpmpgp.h>
#include <rpm/rpmcli.h>
#include <rpm/rpmfileutil.h> /* rpmMkTempFile() */
#include <rpm/rpmfileutil.h> /* rpmMkTemp() */
#include <rpm/rpmdb.h>
#include <rpm/rpmts.h>
#include <rpm/rpmlog.h>
@ -199,8 +199,9 @@ static int rpmReSign(rpmts ts, QVA_t qva, ARGV_const_t argv)
msg = _free(msg);
/* ASSERT: ofd == NULL && sigtarget == NULL */
if (rpmMkTempFile(NULL, &sigtarget, &ofd)) {
rpmlog(RPMLOG_ERR, _("rpmMkTempFile failed\n"));
ofd = rpmMkTemp(NULL, &sigtarget);
if (ofd == NULL || Ferror(ofd)) {
rpmlog(RPMLOG_ERR, _("rpmMkTemp failed\n"));
rc = RPMRC_FAIL;
goto exit;
}

View File

@ -675,8 +675,9 @@ static int makeHDRSignature(Header sigh, const char * file, rpmSigTag sigTag,
h = headerRead(fd, HEADER_MAGIC_YES);
if (h == NULL)
goto exit;
(void) Fclose(fd); fd = NULL;
if (rpmMkTempFile(NULL, &fn, &fd))
(void) Fclose(fd);
fd = rpmMkTemp(NULL, &fn);
if (fd == NULL || Ferror(fd))
goto exit;
if (headerWrite(fd, h, HEADER_MAGIC_YES))
goto exit;
@ -693,8 +694,9 @@ static int makeHDRSignature(Header sigh, const char * file, rpmSigTag sigTag,
h = headerRead(fd, HEADER_MAGIC_YES);
if (h == NULL)
goto exit;
(void) Fclose(fd); fd = NULL;
if (rpmMkTempFile(NULL, &fn, &fd))
(void) Fclose(fd);
fd = rpmMkTemp(NULL, &fn);
if (fd == NULL || Ferror(fd))
goto exit;
if (headerWrite(fd, h, HEADER_MAGIC_YES))
goto exit;

View File

@ -225,15 +225,13 @@ exit:
return rc;
}
int rpmMkTempFile(const char * prefix, char ** fnptr, FD_t * fdptr)
FD_t rpmMkTemp(const char * prefix, char **fn)
{
const char * tpmacro = "%{?_tmppath:%{_tmppath}}%{!?_tmppath:" LOCALSTATEDIR "/tmp}";
char * tempfn = NULL;
const char * tfn = NULL;
const char *tpmacro = "%{_tmppath}"; /* always set from rpmrc */
char *tempfn;
int sfd;
static int _initialized = 0;
int temput;
FD_t fd = NULL;
int ran;
FD_t tfd = NULL;
if (!prefix) prefix = "";
@ -242,86 +240,31 @@ int rpmMkTempFile(const char * prefix, char ** fnptr, FD_t * fdptr)
_initialized = 1;
tempfn = rpmGenPath(prefix, tpmacro, NULL);
if (rpmioMkpath(tempfn, 0755, (uid_t) -1, (gid_t) -1))
goto errxit;
goto exit;
free(tempfn);
}
/* XXX should probably use mkstemp here */
srand(time(NULL));
ran = rand() % 100000;
/* maybe this should use link/stat? */
do {
char tfnbuf[64];
#ifndef NOTYET
sprintf(tfnbuf, "rpm-tmp.%d", ran++);
tempfn = _free(tempfn);
tempfn = rpmGenPath(prefix, tpmacro, tfnbuf);
#else
strcpy(tfnbuf, "rpm-tmp.XXXXXX");
tempfn = _free(tempfn);
tempfn = rpmGenPath(prefix, tpmacro, mktemp(tfnbuf));
#endif
temput = urlPath(tempfn, &tfn);
if (*tfn == '\0') goto errxit;
switch (temput) {
case URL_IS_DASH:
case URL_IS_HKP:
goto errxit;
break;
case URL_IS_HTTPS:
case URL_IS_HTTP:
case URL_IS_FTP:
default:
break;
}
fd = Fopen(tempfn, "w+x.ufdio");
/* XXX FIXME: errno may not be correct for ufdio */
} while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
if (fd == NULL || Ferror(fd))
goto errxit;
switch(temput) {
case URL_IS_PATH:
case URL_IS_UNKNOWN:
{ struct stat sb, sb2;
if (!stat(tfn, &sb) && S_ISLNK(sb.st_mode)) {
rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn);
goto errxit;
}
if (sb.st_nlink != 1) {
rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn);
goto errxit;
}
if (fstat(Fileno(fd), &sb2) == 0) {
if (sb2.st_ino != sb.st_ino || sb2.st_dev != sb.st_dev) {
rpmlog(RPMLOG_ERR, _("error creating temporary file %s\n"), tfn);
goto errxit;
}
}
} break;
default:
break;
tempfn = rpmGetPath(prefix, tpmacro, "/rpm-tmp.XXXXXX", NULL);
sfd = mkstemp(tempfn);
if (sfd < 0) {
rpmlog(RPMLOG_ERR, _("error creating temporary file: %m\n"));
goto exit;
}
if (fnptr)
*fnptr = tempfn;
else
tempfn = _free(tempfn);
*fdptr = fd;
tfd = fdDup(sfd);
close(sfd);
if (tfd == NULL || Ferror(tfd)) {
rpmlog(RPMLOG_ERR, _("error opening temporary file %s: %m\n"), tempfn);
goto exit;
}
return 0;
exit:
if (tfd != NULL && fn)
*fn = tempfn;
else
free(tempfn);
errxit:
tempfn = _free(tempfn);
if (fd != NULL) (void) Fclose(fd);
return 1;
return tfd;
}
int rpmioMkpath(const char * path, mode_t mode, uid_t uid, gid_t gid)

View File

@ -32,21 +32,17 @@ typedef enum rpmCompressedMagic_e {
int rpmDoDigest(pgpHashAlgo algo, const char * fn,int asAscii,
unsigned char * digest, rpm_off_t * fsizep);
/** \ingroup rpmfileutil
* Return file handle for a temporaray file.
* A unique temporaray file path will be generated using
* rpmGenPath(prefix, "%{_tmppath}/", "rpm-tmp.XXXXX")
* where "XXXXXX" is filled in using rand(3). The file is opened, and
* the link count and (dev,ino) location are verified after opening.
* A unique temporaray file path will be created in
* [prefix/]%{_tmppath} directory.
* The file name and the open file handle are returned.
*
* @param prefix leading part of temp file path
* @retval fnptr temp file name (or NULL)
* @retval fdptr temp file handle
* @return 0 on success
* @return fdptr open file handle or NULL on error
*/
int rpmMkTempFile(const char * prefix, char ** fnptr, FD_t * fdptr);
FD_t rpmMkTemp(const char * prefix, char **fn);
/** \ingroup rpmfileutil
* Insure that directories in path exist, creating as needed.