32 #include <boost/algorithm/string.hpp>
33 #include <boost/scoped_array.hpp>
34 #include <boost/thread.hpp>
36 using boost::algorithm::to_lower_copy;
37 namespace fs = boost::filesystem;
65 # define _CRT_SECURE_NO_WARNINGS // Sembla que no funciona
67 # pragma warning( disable: 4996 ) // Warning associat a funcions insegures
71 #undef TFC_CANVI_DE_PAGINA
72 #undef TFC_CANVI_DE_MODE
77 # ifdef TFC_CANVI_DE_PAGINA
78 UINT codepage_inicial;
83 std::wstring utf_a_wstr(
const std::string& s)
85 const int slength = (int)s.length() + 1;
86 const int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, 0, 0);
89 buf =
new wchar_t[len];
90 MultiByteToWideChar(CP_UTF8, 0, s.c_str(), slength, buf, len);
102 # ifdef TFC_CANVI_DE_PAGINA
103 codepage_inicial = ::GetConsoleOutputCP();
104 ::SetConsoleOutputCP(CP_UTF8);
106 # ifdef TFC_CANVI_DE_MODE
107 _setmode(_fileno(stdout), _O_U8TEXT);
108 _setmode(_fileno(stderr), _O_U8TEXT);
113 # ifdef TFC_CANVI_DE_PAGINA
115 ::SetConsoleOutputCP(codepage_inicial);
119 # define canvia_consola_a_utf8()
120 # define restaura_consola()
137 namespace portabilitat {
144 ::setlocale(LC_TIME,
"C");
157 string getenv(
const string & var,
bool * existeix) {
158 boost::unique_lock<boost::mutex> lock(
env_mtx);
174 ::getenv_s(&bufsize, NULL, 0, var.c_str());
185 boost::scoped_array<char> val(
new char[bufsize]);
186 ::getenv_s(&bufsize, val.get(), bufsize, val.get());
187 return string(val.get());
188 #endif // Codi mort: getenv_s() (Windows)
191 *existeix = ( 0 != val );
199 bool setenv(
const string & var,
const string & valor) {
200 boost::unique_lock<boost::mutex> lock(
env_mtx);
207 const string cat(var.c_str()+string(
"=")+valor.c_str());
208 const int ret = ::_putenv(cat.c_str());
211 const int ret =
::setenv(var.c_str(), valor.c_str(), 1);
218 # error Cap forma suportada de modificar l`entorn
219 # endif // setenv/putenv
220 #endif // Windows / POSIX
230 # ifdef HAVE_UNSETENV
231 boost::unique_lock<boost::mutex> lock(
env_mtx);
235 # error Cap forma suportada de modificar l`entorn
243 static const string MISSATGE_ERROR(
"Error obtenint el directori temporal");
246 DWORD buflen = ::GetTempPath(0, const_cast<LPSTR>(
""));
248 throw runtime_error(MISSATGE_ERROR);
250 vector<char> buf(buflen);
251 buflen = ::GetTempPath(static_cast<DWORD>(buf.size()), &buf[0]);
252 if (0 == buflen || buf.size() < buflen) {
253 throw runtime_error(MISSATGE_ERROR);
255 d.assign(buf.begin(), buf.begin()+buflen);
261 d =
getenv(
"TMPDIR", &existeix);
275 throw (runtime_error) {
276 static const string MISSATGE_ERROR(
"Error en crear fitxer temporal");
283 char buffer[MAX_PATH];
284 UINT ret = ::GetTempFileName(dir.c_str(), patro.c_str(), 0, buffer);
286 throw runtime_error(MISSATGE_ERROR);
288 nom.assign(buffer, buffer+ret);
289 shared_ptr<ofstream> pofs(
new ofstream(
nom.c_str(), ios::out|ios::binary));
292 vector<char> buf(dir.begin(), dir.end());
294 buf.insert(buf.end(), patro.begin(), patro.end());
296 buf.insert(buf.end(), 6,
'X');
298 int fd = ::mkstemp(&buf[0]);
300 throw runtime_error(&buf[0]);
301 throw runtime_error(MISSATGE_ERROR+
";1");
303 nom.assign(buf.begin(), buf.end());
305 shared_ptr<ofstream> pofs(
new ofstream(
nom.c_str(), ios::out|ios::binary));
307 throw runtime_error(MISSATGE_ERROR+
";2");
312 # error Cap forma suportada de crear fitxers temporals
324 # ifdef HAVE_UNISTD_H
327 # ifdef HAVE_SYS_TYPES_H
328 # include <sys/types.h>
330 # ifdef HAVE_SYS_STAT_H
331 # include <sys/stat.h>
337 namespace portabilitat {
343 assert( fs::is_regular_file(f) );
347 if (!f.has_extension()) {
350 const string ext = to_lower_copy(f.extension().string());
353 return (
".exe" == ext ||
".com" == ext );
357 ::stat(f.string().c_str(), &st);
358 if (0 == (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) {
362 const uid_t euid = ::geteuid();
363 const gid_t egid = ::getegid();
365 if (euid == st.st_uid) {
366 permis = (0 != (S_IXUSR|st.st_mode));
368 else if (egid == st.st_gid) {
369 permis = (0 != (S_IXGRP|st.st_mode));
372 permis = (0 != (S_IXOTH|st.st_mode));