1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
*
* Copyright (C) 2011-2021, OFFIS e.V.
* All rights reserved. See COPYRIGHT file for details.
*
* This software and supporting documentation were developed by
*
* OFFIS e.V.
* R&D Division Health
* Escherweg 2
* D-26121 Oldenburg, Germany
*
*
* Module: ofstd
*
* Author: Uli Schlachter
*
* Purpose: Defines a class which manages a temporary file
*
*/
#include "dcmtk/config/osconfig.h"
#include "dcmtk/ofstd/oftempf.h"
#include "dcmtk/ofstd/offname.h"
#include "dcmtk/ofstd/ofstd.h"
#include "dcmtk/ofstd/ofstdinc.h"
#include <ctime>
BEGIN_EXTERN_C
#ifdef HAVE_IO_H
#include <io.h> /* for open() and close() on Win32 */
#endif
END_EXTERN_C
#ifdef HAVE_WINDOWS_H
#define WIN32_LEAN_AND_MEAN
#include <windows.h> /* for GetTempPath() */
#endif
/* Maximum number of attempts to open a temporary file. Please not that
* OFFilenameCreator already retries in a loop, so this can be quite low.
*/
#define MAX_ATTEMPTS 5
OFTempFile::OFTempFile(unsigned int flags, const OFString& dir, const OFString& prefix, const OFString& postfix)
: m_status(EC_Normal /* no default constructor */)
, m_fileName()
, m_fileHandle(-1)
{
m_status = createFile(m_fileName, &m_fileHandle, flags, dir, prefix, postfix);
}
OFTempFile::~OFTempFile()
{
if (m_fileHandle >= 0)
close(m_fileHandle);
m_fileHandle = -1;
if (!m_fileName.empty())
unlink(m_fileName.c_str());
m_fileName.clear();
}
void OFTempFile::stealFile(OFBool dontCloseHandle)
{
if (!dontCloseHandle)
close(m_fileHandle);
m_fileName.clear();
m_fileHandle = -1;
}
OFCondition OFTempFile::createFile(OFString& fileName, int* fd_out, unsigned int flags,
const OFString& dir, const OFString& prefix, const OFString& postfix)
{
OFFilenameCreator creator;
unsigned int seed = OFstatic_cast(unsigned int, time(NULL));
unsigned int attempt;
OFCondition status = EC_Normal;
OFString tempDir;
const char *pdir;
int fd = -1;
if (dir.empty())
{
getTempPath(tempDir);
pdir = tempDir.c_str();
}
else
{
pdir = dir.c_str();
}
for (attempt = 0; attempt < MAX_ATTEMPTS; attempt++)
{
OFBool ok = creator.makeFilename(seed, pdir, prefix.c_str(), postfix.c_str(), fileName);
if (ok)
{
// Please note that O_CREAT|O_EXCL makes sure that the file didn't
// exist yet. This might seem unneeded since OFFileNameCreator
// already checked, but someone might have created the file since
// that check.
fd = open(fileName.c_str(), flags|O_CREAT|O_EXCL, 0600);
if (fd >= 0)
break;
}
}
if (fd < 0)
{
fileName.clear();
fd = -1;
status = EC_CouldNotCreateTemporaryFile;
}
if (fd_out)
*fd_out = fd;
else
close(fd);
return status;
}
void OFTempFile::getTempPath(OFString& sPath)
{
// We could also try getenv("TMPDIR"), if getenv() is available.
#ifdef _WIN32
#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];
GetTempPathA(BUFFER_SIZE, buffer);
sPath = buffer;
#elif defined(__ANDROID__)
sPath = ANDROID_TEMPORARY_FILES_LOCATION;
#else
sPath = "/tmp";
#endif
}
|