diff --git a/src/utils/pathut.cpp b/src/utils/pathut.cpp index b4b48e1d..32428f6e 100644 --- a/src/utils/pathut.cpp +++ b/src/utils/pathut.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: pathut.cpp,v 1.12 2006-12-14 13:53:43 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: pathut.cpp,v 1.13 2006-12-16 15:31:51 dockes Exp $ (C) 2004 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -20,6 +20,7 @@ static char rcsid[] = "@(#$Id: pathut.cpp,v 1.12 2006-12-14 13:53:43 dockes Exp #ifndef TEST_PATHUT #include +#include #include #include @@ -34,45 +35,85 @@ using std::stack; #include "pathut.h" -bool maketmpdir(string& tdir, string& reason) +static const char *tmplocation() { const char *tmpdir = getenv("RECOLL_TMPDIR"); if (!tmpdir) tmpdir = getenv("TMPDIR"); if (!tmpdir) tmpdir = "/tmp"; - tdir = path_cat(tmpdir, "rcltmpXXXXXX"); + return tmpdir; +} - { - char *cp = strdup(tdir.c_str()); - if (!cp) { - reason = "maketmpdir: out of memory (for file name !)\n"; - tdir.erase(); - return false; - } -#ifdef HAVE_MKDTEMP - if (!mkdtemp(cp)) { -#else - if (!mktemp(cp)) { -#endif // HAVE_MKDTEMP - free(cp); - reason = "maketmpdir: mktemp failed\n"; - tdir.erase(); - return false; - } - tdir = cp; - free(cp); +bool maketmpdir(string& tdir, string& reason) +{ + tdir = path_cat(tmplocation(), "rcltmpXXXXXX"); + + char *cp = strdup(tdir.c_str()); + if (!cp) { + reason = "maketmpdir: out of memory (for file name !)\n"; + tdir.erase(); + return false; } + + if (! +#ifdef HAVE_MKDTEMP + mkdtemp(cp) +#else + mktemp(cp) +#endif // HAVE_MKDTEMP + ) { + free(cp); + reason = "maketmpdir: mktemp failed\n"; + tdir.erase(); + return false; + } + tdir = cp; + free(cp); + #ifndef HAVE_MKDTEMP if (mkdir(tdir.c_str(), 0700) < 0) { - reason = string("maketmpdir: mkdir ) + tdir : " failed"; + reason = string("maketmpdir: mkdir ") + tdir + " failed"; tdir.erase(); return false; } #endif + return true; } +TempFileInternal::TempFileInternal(const string& suffix) +{ + string filename = path_cat(tmplocation(), "rcltmpfXXXXXX"); + char *cp = strdup(filename.c_str()); + if (!cp) { + m_reason = "Out of memory (for file name !)\n"; + return; + } + + if (!mktemp(cp)) { + free(cp); + m_reason = "maketmpdir: mktemp failed\n"; + return; + } + filename = cp; + free(cp); + + // Yea not right + m_filename = filename + suffix; + if (close(open(m_filename.c_str(), O_CREAT|O_EXCL, 0600)) != 0) { + m_reason = string("Could not open/create") + m_filename; + m_filename.erase(); + } +} + +TempFileInternal::~TempFileInternal() +{ + if (!m_filename.empty()) + unlink(m_filename.c_str()); +} + + void path_catslash(std::string &s) { if (s.empty() || s[s.length() - 1] != '/') s += '/'; diff --git a/src/utils/pathut.h b/src/utils/pathut.h index 51163306..51c200f9 100644 --- a/src/utils/pathut.h +++ b/src/utils/pathut.h @@ -16,10 +16,11 @@ */ #ifndef _PATHUT_H_INCLUDED_ #define _PATHUT_H_INCLUDED_ -/* @(#$Id: pathut.h,v 1.10 2006-12-14 13:53:43 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: pathut.h,v 1.11 2006-12-16 15:31:51 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include +#include "refcntr.h" #ifndef NO_NAMESPACES using std::string; @@ -54,4 +55,19 @@ extern bool path_isdir(const string& path); /// Create temporary directory extern bool maketmpdir(string& tdir, string& reason); +/// Temporary file class +class TempFileInternal { +public: + TempFileInternal(const string& suffix); + ~TempFileInternal(); + const char *filename() {return m_filename.c_str();} + const string &getreason() {return m_reason;} + bool ok() {return !m_filename.empty();} +private: + string m_filename; + string m_reason; +}; + +typedef RefCntr TempFile; + #endif /* _PATHUT_H_INCLUDED_ */