]> git.lyx.org Git - features.git/blob - src/support/tempname.cpp
049b863d7e5a4bd5f39798fcf2c80d873608a982
[features.git] / src / support / tempname.cpp
1 /**
2  * \file tempname.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "support/lyxlib.h"
14
15 #include "support/convert.h"
16 #include "support/filetools.h"
17 #include "support/Package.h"
18
19 #include "debug.h"
20
21 #include <boost/scoped_array.hpp>
22
23 #include <cstdlib>
24
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28
29 #if defined(HAVE_MKSTEMP) && ! defined(HAVE_DECL_MKSTEMP)
30 extern "C" int mkstemp(char *);
31 #endif
32
33 #if !defined(HAVE_MKSTEMP) && defined(HAVE_MKTEMP)
34 # include <fcntl.h>
35 # ifdef HAVE_SYS_STAT_H
36 #  include <sys/stat.h>
37 # endif
38 # ifdef HAVE_IO_H
39 #  include <io.h>
40 # endif
41 # ifdef HAVE_PROCESS_H
42 #  include <process.h>
43 # endif
44 #endif
45
46 using boost::scoped_array;
47
48 using std::string;
49 using std::endl;
50
51 namespace lyx {
52 namespace support {
53
54 namespace {
55
56 inline
57 int make_tempfile(char * templ)
58 {
59 #if defined(HAVE_MKSTEMP)
60         return ::mkstemp(templ);
61 #elif defined(HAVE_MKTEMP)
62         // This probably just barely works...
63         ::mktemp(templ);
64 # if defined (HAVE_OPEN)
65 # if (!defined S_IRUSR)
66 #   define S_IRUSR S_IREAD
67 #   define S_IWUSR S_IWRITE
68 # endif
69         return ::open(templ, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
70 # elif defined (HAVE__OPEN)
71         return ::_open(templ,
72                        _O_RDWR | _O_CREAT | _O_EXCL,
73                        _S_IREAD | _S_IWRITE);
74 # else
75 #  error No open() function.
76 # endif
77 #else
78 #error FIX FIX FIX
79 #endif
80 }
81
82 } // namespace anon
83
84
85 FileName const tempName(FileName const & dir, string const & mask)
86 {
87         string const tmpdir(dir.empty() ?
88                         package().temp_dir().absFilename() :
89                         dir.absFilename());
90         string tmpfl(to_filesystem8bit(from_utf8(addName(tmpdir, mask))));
91 #if defined (HAVE_GETPID)
92         tmpfl += convert<string>(getpid());
93 #elif defined (HAVE__GETPID)
94         tmpfl += convert<string>(_getpid());
95 #else
96 # error No getpid() function
97 #endif
98         tmpfl += "XXXXXX";
99
100         // The supposedly safe mkstemp version
101         scoped_array<char> tmpl(new char[tmpfl.length() + 1]); // + 1 for '\0'
102         tmpfl.copy(tmpl.get(), string::npos);
103         tmpl[tmpfl.length()] = '\0'; // terminator
104
105         int const tmpf = make_tempfile(tmpl.get());
106         if (tmpf != -1) {
107                 string const t(to_utf8(from_filesystem8bit(tmpl.get())));
108 #if defined (HAVE_CLOSE)
109                 ::close(tmpf);
110 #elif defined (HAVE__CLOSE)
111                 ::_close(tmpf);
112 #else
113 # error No x() function.
114 #endif
115                 LYXERR(Debug::FILES) << "Temporary file `" << t
116                                      << "' created." << endl;
117                 return FileName(t);
118         } else {
119                 LYXERR(Debug::FILES)
120                         << "LyX Error: Unable to create temporary file."
121                         << endl;
122                 return FileName();
123         }
124 }
125
126 } // namespace support
127 } // namespace lyx