#include <config.h>
+#include "LyX.h"
#include "LyXRC.h"
#include "support/filetools.h"
+#include "support/convert.h"
#include "support/debug.h"
#include "support/environment.h"
#include "support/gettext.h"
#include "support/PathChanger.h"
#include "support/Systemcall.h"
#include "support/qstring_helpers.h"
+#include "support/TempFile.h"
#include <QDir>
#include <QTemporaryFile>
#endif
#include <cerrno>
+#include <climits>
#include <cstdlib>
#include <cstdio>
}
+FileName const tempFileName(string const & mask)
+{
+ FileName tempfile = TempFile(mask).name();
+ // Since the QTemporaryFile object is destroyed at function return
+ // (which is what is intended here), the next call to this function
+ // may return the same file name again.
+ // Thus, in order to prevent race conditions, we track returned names
+ // and create our own unique names if QTemporaryFile returns a name again.
+ if (tmp_names_.find(tempfile.absFileName()) == tmp_names_.end()) {
+ tmp_names_.insert(tempfile.absFileName());
+ return tempfile;
+ }
+
+ // OK, we need another name. Simply append digits.
+ FileName tmp = tempfile;
+ tmp.changeExtension("");
+ for (int i = 1; i < INT_MAX ;++i) {
+ // Append digit to filename and re-add extension
+ string const new_fn = tmp.absFileName() + convert<string>(i)
+ + "." + tempfile.extension();
+ if (tmp_names_.find(new_fn) == tmp_names_.end()) {
+ tmp_names_.insert(new_fn);
+ tempfile.set(new_fn);
+ return tempfile;
+ }
+ }
+
+ // This should not happen!
+ LYXERR0("tempFileName(): Could not create unique temp file name!");
+ return tempfile;
+}
+
+
+void removeTempFile(FileName const & fn)
+{
+ if (!fn.exists())
+ return;
+
+ string const abs = fn.absFileName();
+ if (tmp_names_.find(abs) != tmp_names_.end())
+ tmp_names_.erase(abs);
+ fn.removeFile();
+}
+
+
static string createTempFile(QString const & mask)
{
// FIXME: This is not safe. QTemporaryFile creates a file in open(),
// same file again. To make this safe the QTemporaryFile object
// needs to be kept for the whole life time of the temp file name.
// This could be achieved by creating a class TempDir (like
- // TempFile, but using a currentlky non-existing
+ // TempFile, but using a currently non-existing
// QTemporaryDirectory object).
QTemporaryFile qt_tmp(mask + ".XXXXXXXXXXXX");
if (qt_tmp.open()) {
}
-// Create absolute path. If impossible, don't do anything
-// Supports ./ and ~/. Later we can add support for ~logname/. (Asger)
-string const expandPath(string const & path)
-{
- // checks for already absolute path
- string rTemp = replaceEnvironmentPath(path);
- if (FileName::isAbsolute(rTemp))
- return rTemp;
-
- string temp;
- string const copy = rTemp;
-
- // Split by next /
- rTemp = split(rTemp, temp, '/');
-
- if (temp == ".")
- return FileName::getcwd().absFileName() + '/' + rTemp;
-
- if (temp == "~")
- return Package::get_home_dir().absFileName() + '/' + rTemp;
-
- if (temp == "..")
- return makeAbsPath(copy).absFileName();
-
- // Don't know how to handle this
- return copy;
-}
-
-
// Search the string for ${VAR} and $VAR and replace VAR using getenv.
string const replaceEnvironmentPath(string const & path)
{
string texinputs_prefix = lyxrc.texinputs_prefix.empty() ? string()
: os::latex_path_list(
replaceCurdirPath(path, lyxrc.texinputs_prefix));
+ string const allother_prefix = os::latex_path_list(path);
string const sep = string(1, os::path_separator(os::TEXENGINE));
string const texinputs = getEnv("TEXINPUTS");
+ string const bibinputs = getEnv("BIBINPUTS");
+ string const bstinputs = getEnv("BSTINPUTS");
+ string const texfonts = getEnv("TEXFONTS");
if (use_lpath) {
string const abslpath = FileName::isAbsolute(lpath)
if (os::shell() == os::UNIX)
return "env TEXINPUTS=\"." + sep + texinputs_prefix
- + sep + texinputs + "\" ";
+ + sep + texinputs + "\" "
+ + "BIBINPUTS=\"." + sep + allother_prefix
+ + sep + bibinputs + "\" "
+ + "BSTINPUTS=\"." + sep + allother_prefix
+ + sep + bstinputs + "\" "
+ + "TEXFONTS=\"." + sep + allother_prefix
+ + sep + texfonts + "\" ";
else
- // NOTE: the dummy blank dir is necessary to force the
+ // NOTE: the dummy blank dirs are necessary to force the
// QProcess parser to quote the argument (see bug 9453)
return "cmd /d /c set \"TEXINPUTS=." + sep + " "
- + sep + texinputs_prefix
- + sep + texinputs + "\" & ";
+ + sep + texinputs_prefix
+ + sep + texinputs + "\" & "
+ + "set \"BIBINPUTS=." + sep + " "
+ + sep + allother_prefix
+ + sep + bibinputs + "\" & "
+ + "set \"BSTINPUTS=." + sep + " "
+ + sep + allother_prefix
+ + sep + bstinputs + "\" & "
+ + "set \"TEXFONTS=." + sep + " "
+ + sep + allother_prefix
+ + sep + texfonts + "\" & ";
}
if (dstr.empty()) {
// Yes, filename itself is too long.
// Pick the start and the end of the filename.
- dstr = from_utf8(onlyFileName(path));
- docstring const head = dstr.substr(0, threshold / 2 - 3);
-
- docstring::size_type len = dstr.length();
- docstring const tail =
- dstr.substr(len - threshold / 2 - 2, len - 1);
- dstr = head + from_ascii("...") + tail;
+ docstring fstr = from_utf8(onlyFileName(path));
+ dstr = fstr;
+ if (support::truncateWithEllipsis(dstr, threshold / 2))
+ dstr += fstr.substr(fstr.length() - threshold / 2 - 2,
+ docstring::npos);
}
return from_utf8(os::external_path(prefix + to_utf8(dstr)));
// pstream (process stream), with the
// variants ipstream, opstream
+ if (verbose)
+ lyxerr << "\nRunning: " << cmd << endl;
+ else
+ LYXERR(Debug::INFO,"Running: " << cmd);
+
#if defined (_WIN32)
- int fno;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
0, 0, &startup, &process)) {
CloseHandle(process.hThread);
- fno = _open_osfhandle((long)in, _O_RDONLY);
+ int fno = _open_osfhandle((intptr_t)in, _O_RDONLY);
CloseHandle(out);
inf = _fdopen(fno, "r");
}
#if defined (_WIN32)
WaitForSingleObject(process.hProcess, INFINITE);
+ DWORD pret;
+ if (!GetExitCodeProcess(process.hProcess, &pret))
+ pret = -1;
if (!infile.empty())
CloseHandle(startup.hStdInput);
CloseHandle(process.hProcess);
- int const pret = fclose(inf);
+ if (fclose(inf) != 0)
+ pret = -1;
#elif defined (HAVE_PCLOSE)
int const pret = pclose(inf);
#elif defined (HAVE__PCLOSE)
}
-FileName const findtexfile(string const & fil, string const & /*format*/)
+FileName const findtexfile(string const & fil, string const & /*format*/,
+ bool const onlykpse)
{
/* There is no problem to extend this function too use other
methods to look for files. It could be setup to look
// If the file can be found directly, we just return a
// absolute path version of it.
- FileName const absfile(makeAbsPath(fil));
- if (absfile.exists())
- return absfile;
+ if (!onlykpse) {
+ FileName const absfile(makeAbsPath(fil));
+ if (absfile.exists())
+ return absfile;
+ }
// Now we try to find it using kpsewhich.
// It seems from the kpsewhich manual page that it is safe to use
int fd = -1;
#if defined(HAVE_LOCKF)
fd = open(lock_file, O_CREAT|O_APPEND|O_SYNC|O_RDWR, 0666);
+ if (fd == -1)
+ return -1;
if (lockf(fd, F_LOCK, 0) != 0) {
close(fd);
- return(-1);
+ return -1;
}
#endif
- return(fd);
+ return fd;
}
+
void fileUnlock(int fd, const char * /* lock_file*/)
{
#if defined(HAVE_LOCKF)