I've mentioned this before. The attached file bundles the contents of 
these files into one, making it simple to find the function declared 
in lyxlib.h and removing clutter from the support dir.

abort.C  chdir.C  getcwd.C  putenv.C  rmdir.C     unlink.C
atoi.C   copy.C   kill.C    rename.C  tempname.C

Any objections to me committing this?

-- 
Angus
/**
 * \file lyxlib.C
 * 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 <config.h>

#include "support/lyxlib.h"

#include "debug.h"

#include "support/filetools.h"
#include "support/os.h"
#include "support/tostr.h"

#include <csignal>
#include <fstream>

#include <fcntl.h>
#include <unistd.h>

using std::string;


void lyx::support::abort()
{
	::abort();
}


int lyx::support::atoi(string const & nstr)
{
#ifndef CXX_GLOBAL_CSTD
using std::atoi;
#endif

	return ::atoi(nstr.c_str());
}


int lyx::support::chdir(string const & name)
{
#ifndef __EMX__
	return ::chdir(name.c_str());
#else
	return ::_chdir2(name.c_str());
#endif
}


bool lyx::support::copy(string const & from, string const & to)
{
	using std::ifstream;
	using std::ofstream;
	using std::ios;

	ifstream ifs(from.c_str());
	if (!ifs)
		return false;
	ofstream ofs(to.c_str(),
		     ios::binary | ios::out | ios::trunc);
	if (!ofs)
		return false;
	ofs << ifs.rdbuf();
	if (ofs.good())
		return true;
	return false;
}


namespace {

inline
char * l_getcwd(char * buffer, size_t size)
{
#ifndef __EMX__
	return ::getcwd(buffer, size);
#else
	return ::_getcwd2(buffer, size);
#endif
}

} // namespace anon


// Returns current working directory
string const lyx::support::getcwd()
{
	int n = 256;	// Assume path is less than 256 chars
	char * err;
	char * tbuf = new char[n];

	// Safe. Hopefully all getcwds behave this way!
	while (((err = l_getcwd(tbuf, n)) == 0) && (errno == ERANGE)) {
		// Buffer too small, double the buffersize and try again
		delete[] tbuf;
		n = 2 * n;
		tbuf = new char[n];
	}

	string result;
	if (err) result = tbuf;
	delete[] tbuf;
	return result;
}


int lyx::support::kill(int pid, int sig)
{
	return ::kill(pid, sig);
}


int lyx::support::mkdir(string const & pathname, unsigned long int mode)
{
	// FIXME: why don't we have mode_t in lyx::mkdir prototype ??
	return ::mkdir(pathname.c_str(), mode_t(mode));
}


int lyx::support::putenv(char const * str)
{
	return ::putenv(const_cast<char*>(str));
}


bool lyx::support::rename(string const & from, string const & to)
{
#ifdef __EMX__
	unlink(to);
#endif
	if (::rename(from.c_str(), to.c_str()) == -1)
		if (copy(from, to)) {
			unlink(from);
			return true;
		} else
			return false;
	return true;
}


int lyx::support::rmdir(string const & dir)
{
	return ::rmdir(dir.c_str());
}


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);
	return ::open(templ, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
#else
#error FIX FIX FIX
#endif
}

} // namespace anon


string const lyx::support::tempName(string const & dir, string const & mask)
{
	using std::endl;

	string const tmpdir(dir.empty() ? os::getTmpDir() : dir);
	string tmpfl(AddName(tmpdir, mask));
	tmpfl += tostr(getpid());
	tmpfl += "XXXXXX";

	// The supposedly safe mkstemp version
	char * tmpl = new char[tmpfl.length() + 1]; // + 1 for '\0'
	tmpfl.copy(tmpl, string::npos);
	tmpl[tmpfl.length()] = '\0'; // terminator

	int const tmpf = make_tempfile(tmpl);
	if (tmpf != -1) {
		string const t(tmpl);
		::close(tmpf);
		delete [] tmpl;
		lyxerr[Debug::FILES] << "Temporary file `" << t
				     << "' created." << endl;
		return t;
	} else {
		lyxerr[Debug::FILES]
			<< "LyX Error: Unable to create temporary file."
			<< endl;
		delete [] tmpl;
		return string();
	}
}


int lyx::support::unlink(string const & pathname)
{
	return ::unlink(pathname.c_str());
}

Reply via email to