diff --git a/src/Buffer.cpp b/src/Buffer.cpp index f218e99049..f0787ab4ba 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -615,7 +615,7 @@ bool Buffer::readString(string const & s) Lexer lex(0, 0); istringstream is(s); lex.setStream(is); - FileName const name(tempName()); + FileName const name = FileName::tempName(); switch (readFile(lex, name, true)) { case failure: return false; @@ -739,7 +739,7 @@ Buffer::ReadStatus Buffer::readFile(Lexer & lex, FileName const & filename, // lyx2lyx would fail return wrongversion; - FileName const tmpfile(tempName()); + FileName const tmpfile = FileName::tempName(); if (tmpfile.empty()) { Alert::error(_("Conversion failed"), bformat(_("%1$s is from a different" @@ -1922,7 +1922,7 @@ int AutoSaveBuffer::generateChild() // anyway. bool failed = false; - FileName const tmp_ret(tempName(FileName(), "lyxauto")); + FileName const tmp_ret = FileName::tempName(FileName(), "lyxauto"); if (!tmp_ret.empty()) { buffer_.writeFile(tmp_ret); // assume successful write of tmp_ret diff --git a/src/LyXVC.cpp b/src/LyXVC.cpp index 1e595894b8..4518a8076c 100644 --- a/src/LyXVC.cpp +++ b/src/LyXVC.cpp @@ -217,7 +217,7 @@ string const LyXVC::getLogFile() const if (!vcs) return string(); - FileName const tmpf(tempName(FileName(), "lyxvclog")); + FileName const tmpf = FileName::tempName(FileName(), "lyxvclog"); if (tmpf.empty()) { LYXERR(Debug::LYXVC, "Could not generate logfile " << tmpf); return string(); diff --git a/src/TextClass.cpp b/src/TextClass.cpp index a61c52f05a..738a31b3b9 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -433,7 +433,7 @@ bool TextClass::read(FileName const & filename, ReadType rt) if (format != FORMAT) { LYXERR(Debug::TCLASS, "Converting layout file from format " << format << " to " << FORMAT); - FileName const tempfile(tempName()); + FileName const tempfile = FileName::tempName(); error = !layout2layout(filename, tempfile); if (!error) error = read(tempfile, rt); diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp index f826419d71..f9fbce598b 100644 --- a/src/graphics/GraphicsCacheItem.cpp +++ b/src/graphics/GraphicsCacheItem.cpp @@ -372,7 +372,8 @@ void CacheItem::Impl::convertToDisplayFormat() FileName filename; zipped_ = filename_.isZippedFile(); if (zipped_) { - unzipped_filename_ = tempName(FileName(), filename_.toFilesystemEncoding()); + unzipped_filename_ = FileName::tempName(FileName(), + filename_.toFilesystemEncoding()); if (unzipped_filename_.empty()) { setStatus(ErrorConverting); LYXERR(Debug::GRAPHICS, "\tCould not create temporary file."); @@ -415,7 +416,7 @@ void CacheItem::Impl::convertToDisplayFormat() // Add some stuff to create a uniquely named temporary file. // This file is deleted in loadImage after it is loaded into memory. - FileName const to_file_base(tempName(FileName(), "CacheItem")); + FileName const to_file_base = FileName::tempName(FileName(), "CacheItem"); remove_loaded_file_ = true; // Remove the temp file, we only want the name... diff --git a/src/graphics/GraphicsConverter.cpp b/src/graphics/GraphicsConverter.cpp index 1f00028ce7..2898f624f4 100644 --- a/src/graphics/GraphicsConverter.cpp +++ b/src/graphics/GraphicsConverter.cpp @@ -293,7 +293,7 @@ static void build_script(FileName const & from_file, // Remember to remove the temp file because we only want the name... static int counter = 0; string const tmp = "gconvert" + convert(counter++); - FileName const to_base(tempName(FileName(), tmp)); + FileName const to_base = FileName::tempName(FileName(), tmp); to_base.removeFile(); // Create a copy of the file in case the original name contains diff --git a/src/insets/InsetExternal.cpp b/src/insets/InsetExternal.cpp index 8fb3ba80b7..a58af2a068 100644 --- a/src/insets/InsetExternal.cpp +++ b/src/insets/InsetExternal.cpp @@ -65,7 +65,7 @@ namespace external { TempName::TempName() { - FileName const tempname(tempName(FileName(), "lyxext")); + FileName const tempname = FileName::tempName(FileName(), "lyxext"); // FIXME: This is unsafe tempname.removeFile(); // must have an extension for the converter code to work correctly. diff --git a/src/mathed/MathExtern.cpp b/src/mathed/MathExtern.cpp index 19275c6925..1a9938dbe2 100644 --- a/src/mathed/MathExtern.cpp +++ b/src/mathed/MathExtern.cpp @@ -1020,7 +1020,7 @@ namespace { { // In order to avoid parsing problems with command interpreters // we pass input data through a file - FileName const cas_tmpfile(tempName(FileName(), "casinput")); + FileName const cas_tmpfile = FileName::tempName(FileName(), "casinput"); if (cas_tmpfile.empty()) { lyxerr << "Warning: cannot create temporary file." << endl; diff --git a/src/support/FileName.cpp b/src/support/FileName.cpp index 1b4a545f3f..1abdd5ff04 100644 --- a/src/support/FileName.cpp +++ b/src/support/FileName.cpp @@ -13,11 +13,13 @@ #include "support/FileName.h" #include "support/FileNameList.h" +#include "support/convert.h" #include "support/debug.h" #include "support/filetools.h" #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/os.h" +#include "support/Package.h" #include "support/qstring_helpers.h" #include @@ -28,6 +30,7 @@ #include #include +#include #include #include @@ -50,8 +53,26 @@ # include #endif -#include #include +#include + + +#ifdef HAVE_UNISTD_H +# include +#endif + +#if defined(HAVE_MKSTEMP) && ! defined(HAVE_DECL_MKSTEMP) +extern "C" int mkstemp(char *); +#endif + +#if !defined(HAVE_MKSTEMP) && defined(HAVE_MKTEMP) +# ifdef HAVE_IO_H +# include +# endif +# ifdef HAVE_PROCESS_H +# include +# endif +#endif using namespace std; @@ -267,7 +288,7 @@ bool FileName::isDirWritable() const { LYXERR(Debug::FILES, "isDirWriteable: " << *this); - FileName const tmpfl(tempName(*this, "lyxwritetest")); + FileName const tmpfl = FileName::tempName(*this, "lyxwritetest"); if (tmpfl.empty()) return false; @@ -310,9 +331,67 @@ FileNameList FileName::dirList(string const & ext) const } +static int make_tempfile(char * templ) +{ +#if defined(HAVE_MKSTEMP) + return ::mkstemp(templ); +#elif defined(HAVE_MKTEMP) + // This probably just barely works... + ::mktemp(templ); +# if defined (HAVE_OPEN) +# if (!defined S_IRUSR) +# define S_IRUSR S_IREAD +# define S_IWUSR S_IWRITE +# endif + return ::open(templ, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); +# elif defined (HAVE__OPEN) + return ::_open(templ, + _O_RDWR | _O_CREAT | _O_EXCL, + _S_IREAD | _S_IWRITE); +# else +# error No open() function. +# endif +#else +#error FIX FIX FIX +#endif +} + + FileName FileName::tempName(FileName const & dir, string const & mask) { - return support::tempName(dir, mask); + string const tmpdir = dir.empty() ? + package().temp_dir().absFilename() : dir.absFilename(); + string tmpfl = to_filesystem8bit(from_utf8(addName(tmpdir, mask))); +#if defined (HAVE_GETPID) + tmpfl += convert(getpid()); +#elif defined (HAVE__GETPID) + tmpfl += convert(_getpid()); +#else +# error No getpid() function +#endif + tmpfl += "XXXXXX"; + + // The supposedly safe mkstemp version + // FIXME: why not using std::string directly? + boost::scoped_array tmpl(new char[tmpfl.length() + 1]); // + 1 for '\0' + tmpfl.copy(tmpl.get(), string::npos); + tmpl[tmpfl.length()] = '\0'; // terminator + + int const tmpf = make_tempfile(tmpl.get()); + if (tmpf != -1) { + string const t(to_utf8(from_filesystem8bit(tmpl.get()))); +#if defined (HAVE_CLOSE) + ::close(tmpf); +#elif defined (HAVE__CLOSE) + ::_close(tmpf); +#else +# error No x() function. +#endif + LYXERR(Debug::FILES, "Temporary file `" << t << "' created."); + return FileName(t); + } + LYXERR(Debug::FILES, "LyX Error: Unable to create temporary file."); + return FileName(); } diff --git a/src/support/Makefile.am b/src/support/Makefile.am index 2e7f13293d..e2b8a37375 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -93,7 +93,6 @@ liblyxsupport_la_SOURCES = \ SignalSlot.cpp \ SignalSlot.h \ SignalSlotPrivate.h \ - tempname.cpp \ textutils.h \ Translator.h \ Timeout.cpp \ diff --git a/src/support/filetools.cpp b/src/support/filetools.cpp index 8ed4b486b2..f86fe835f6 100644 --- a/src/support/filetools.cpp +++ b/src/support/filetools.cpp @@ -322,8 +322,8 @@ static FileName createTmpDir(FileName const & tempdir, string const & mask) LYXERR(Debug::FILES, "createTmpDir: tempdir=`" << tempdir << "'\n" << "createTmpDir: mask=`" << mask << '\''); - FileName const tmpfl(tempName(tempdir, mask)); - // lyx::tempName actually creates a file to make sure that it + FileName const tmpfl = FileName::tempName(tempdir, mask); + // FileName::tempName actually creates a file to make sure that it // stays unique. So we have to delete it before we can create // a dir with the same name. Note also that we are not thread // safe because of the gap between unlink and mkdir. (Lgb) diff --git a/src/support/lyxlib.h b/src/support/lyxlib.h index 74abd7fefa..bb8ed4eadb 100644 --- a/src/support/lyxlib.h +++ b/src/support/lyxlib.h @@ -31,11 +31,6 @@ int kill(int pid, int sig); /// FIXME: same here void abort(); -/// (securely) create a temporary file in the given dir with the given mask -/// \p mask must be in filesystem encoding -FileName const tempName(FileName const & dir = FileName(), - std::string const & mask = std::string()); - /** * Returns true if var is approximately equal to number with allowed error diff --git a/src/support/tempname.cpp b/src/support/tempname.cpp deleted file mode 100644 index e5d19f30fe..0000000000 --- a/src/support/tempname.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/** - * \file tempname.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Lars Gullik Bjønnes - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "support/lyxlib.h" - -#include "support/convert.h" -#include "support/debug.h" -#include "support/filetools.h" -#include "support/Package.h" - -#include - -#include - -#ifdef HAVE_UNISTD_H -# include -#endif - -#if defined(HAVE_MKSTEMP) && ! defined(HAVE_DECL_MKSTEMP) -extern "C" int mkstemp(char *); -#endif - -#if !defined(HAVE_MKSTEMP) && defined(HAVE_MKTEMP) -# include -# ifdef HAVE_SYS_STAT_H -# include -# endif -# ifdef HAVE_IO_H -# include -# endif -# ifdef HAVE_PROCESS_H -# include -# endif -#endif - -using namespace std; - -using boost::scoped_array; - -namespace lyx { -namespace support { - -namespace { - -inline -int make_tempfile(char * templ) -{ -#if defined(HAVE_MKSTEMP) - return ::mkstemp(templ); -#elif defined(HAVE_MKTEMP) - // This probably just barely works... - ::mktemp(templ); -# if defined (HAVE_OPEN) -# if (!defined S_IRUSR) -# define S_IRUSR S_IREAD -# define S_IWUSR S_IWRITE -# endif - return ::open(templ, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); -# elif defined (HAVE__OPEN) - return ::_open(templ, - _O_RDWR | _O_CREAT | _O_EXCL, - _S_IREAD | _S_IWRITE); -# else -# error No open() function. -# endif -#else -#error FIX FIX FIX -#endif -} - -} // namespace anon - - -FileName const tempName(FileName const & dir, string const & mask) -{ - string const tmpdir = dir.empty() - ? package().temp_dir().absFilename() : dir.absFilename(); - string tmpfl = to_filesystem8bit(from_utf8(addName(tmpdir, mask))); -#if defined (HAVE_GETPID) - tmpfl += convert(getpid()); -#elif defined (HAVE__GETPID) - tmpfl += convert(_getpid()); -#else -# error No getpid() function -#endif - tmpfl += "XXXXXX"; - - // The supposedly safe mkstemp version - scoped_array tmpl(new char[tmpfl.length() + 1]); // + 1 for '\0' - tmpfl.copy(tmpl.get(), string::npos); - tmpl[tmpfl.length()] = '\0'; // terminator - - int const tmpf = make_tempfile(tmpl.get()); - if (tmpf != -1) { - string const t(to_utf8(from_filesystem8bit(tmpl.get()))); -#if defined (HAVE_CLOSE) - ::close(tmpf); -#elif defined (HAVE__CLOSE) - ::_close(tmpf); -#else -# error No x() function. -#endif - LYXERR(Debug::FILES, "Temporary file `" << t << "' created."); - return FileName(t); - } - LYXERR(Debug::FILES, "LyX Error: Unable to create temporary file."); - return FileName(); -} - -} // namespace support -} // namespace lyx