2001-05-17 15:11:01 +00:00
|
|
|
// os_os2.C
|
|
|
|
|
|
|
|
// Various OS specific functions
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "os.h"
|
|
|
|
#include "support/filetools.h"
|
|
|
|
#define INCL_DOSFILEMGR
|
|
|
|
#define INCL_DOSMODULEMGR
|
|
|
|
#define INCL_DOSPROCESS
|
|
|
|
#define INCL_DOSNLS
|
|
|
|
#define INCL_DOSERRORS
|
|
|
|
#include <os2.h>
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
namespace {
|
2001-05-17 15:11:01 +00:00
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
string binpath_;
|
|
|
|
string binname_;
|
|
|
|
string tmpdir_;
|
|
|
|
os::shell_type shell_ = os::UNIX;
|
|
|
|
unsigned long cp_ = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace os {
|
|
|
|
|
|
|
|
|
|
|
|
void init(int * argc, char ** argv[])
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
if (argc != 0 /* This is a hack! */) {
|
|
|
|
_wildcard(argc, argv);
|
|
|
|
PTIB ptib = new TIB[1];
|
|
|
|
PPIB ppib = new PIB[1];
|
|
|
|
APIRET rc = DosGetInfoBlocks(&ptib, &ppib);
|
|
|
|
if (rc != NO_ERROR)
|
|
|
|
exit(rc);
|
|
|
|
char* tmp = new char[256];
|
|
|
|
// This is the only reliable way to retrieve the executable name.
|
|
|
|
rc = DosQueryModuleName(ppib->pib_hmte, 256L, tmp);
|
|
|
|
if (rc != NO_ERROR)
|
|
|
|
exit(rc);
|
2003-02-10 10:22:05 +00:00
|
|
|
string p = tmp;
|
2001-05-17 15:11:01 +00:00
|
|
|
p = slashify_path(p);
|
|
|
|
binname_ = OnlyFilename(p);
|
|
|
|
binname_.erase(binname_.length()-4, string::npos);
|
|
|
|
binpath_ = OnlyPath(p);
|
|
|
|
|
|
|
|
// OS/2 cmd.exe has another use for '&'
|
|
|
|
string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
|
|
|
|
if (sh.empty()) {
|
|
|
|
// COMSPEC is set, unless user unsets
|
|
|
|
sh = OnlyFilename(GetEnvPath("COMSPEC"));
|
|
|
|
if (sh.empty())
|
|
|
|
sh = "cmd.exe";
|
|
|
|
}
|
|
|
|
sh = lowercase(sh); // DosMapCase() is an overkill here
|
2003-02-10 10:22:05 +00:00
|
|
|
if (contains(sh, "cmd.exe") || contains(sh, "4os2.exe"))
|
|
|
|
shell_ = os::CMD_EXE;
|
2001-05-17 15:11:01 +00:00
|
|
|
else
|
2003-02-10 10:22:05 +00:00
|
|
|
shell_ = os::UNIX;
|
2001-05-17 15:11:01 +00:00
|
|
|
}
|
2003-02-10 10:22:05 +00:00
|
|
|
|
2001-05-17 15:11:01 +00:00
|
|
|
static bool initialized = false;
|
2003-02-10 10:22:05 +00:00
|
|
|
if (initialized)
|
|
|
|
return;
|
2001-05-17 15:11:01 +00:00
|
|
|
initialized = true;
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
ULONG CPList[3] = {0};
|
|
|
|
ULONG CPList_size;
|
2001-05-17 15:11:01 +00:00
|
|
|
APIRET rc = DosQueryCp(3 * sizeof(ULONG), CPList, &CPList_size);
|
|
|
|
if (rc != NO_ERROR)
|
|
|
|
exit(rc);
|
|
|
|
// CPList[0] == process current codepage,
|
|
|
|
// CPList[1] == system default codepage, the rest are auxilary.
|
|
|
|
// Once cp_ is correctly set, you can call other routines.
|
|
|
|
cp_ = CPList[1];
|
|
|
|
}
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
void warn(string const & /*mesg*/)
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
string current_root()
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
APIRET rc;
|
2003-02-10 10:22:05 +00:00
|
|
|
ULONG drv_num;
|
|
|
|
ULONG drv_map;
|
2001-05-17 15:11:01 +00:00
|
|
|
rc = DosQueryCurrentDisk(&drv_num, &drv_map);
|
|
|
|
if (rc != NO_ERROR)
|
|
|
|
exit(rc);
|
|
|
|
char drive = 'A' + drv_num -1;
|
|
|
|
string tmp(1, drive);
|
|
|
|
tmp += ":/";
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
string::size_type common_path(string const & p1, string const & p2)
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
static bool initialized = false;
|
|
|
|
if (!initialized) {
|
|
|
|
init(0, 0);
|
|
|
|
initialized = true;
|
|
|
|
}
|
2003-02-10 10:22:05 +00:00
|
|
|
|
2001-05-17 15:11:01 +00:00
|
|
|
COUNTRYCODE cntry;
|
|
|
|
cntry.country = 0;
|
|
|
|
cntry.codepage = cp_;
|
|
|
|
string temp1 = slashify_path(p1);
|
|
|
|
string temp2 = slashify_path(p2);
|
2003-02-10 10:22:05 +00:00
|
|
|
char * tmp1 = const_cast<char *> (temp1.c_str());
|
|
|
|
char * tmp2 = const_cast<char *> (temp2.c_str());
|
2001-05-17 15:11:01 +00:00
|
|
|
/* rc = */ DosMapCase(p1.length(), &cntry, tmp1);
|
|
|
|
// if (rc != NO_ERROR)
|
|
|
|
// exit(rc);
|
|
|
|
/* rc = */ DosMapCase(p2.length(), &cntry, tmp2);
|
|
|
|
// if (rc != NO_ERROR)
|
|
|
|
// exit(rc);
|
|
|
|
// This algorithm works only if paths are slashified on DBCS systems.
|
2003-02-10 10:22:05 +00:00
|
|
|
string::size_type i = 0;
|
|
|
|
string::size_type p1_len = p1.length();
|
|
|
|
string::size_type p2_len = p2.length();
|
|
|
|
while (i < p1_len && i < p2_len && tmp1[i] == tmp2[i])
|
|
|
|
++i;
|
2001-05-17 15:11:01 +00:00
|
|
|
if ((i < p1_len && i < p2_len)
|
|
|
|
|| (i < p1_len && tmp1[i] != '/' && i == p2_len)
|
2003-02-10 10:22:05 +00:00
|
|
|
|| (i < p2_len && tmp2[i] != '/' && i == p1_len))
|
|
|
|
{
|
|
|
|
if (i)
|
|
|
|
--i; // here was the last match
|
|
|
|
while (i && tmp1[i] != '/')
|
|
|
|
--i;
|
2001-05-17 15:11:01 +00:00
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
string slashify_path(string const & p)
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
static bool initialized = false;
|
|
|
|
static bool leadbyte[256] = {false};
|
|
|
|
if (!initialized) {
|
|
|
|
init(0, 0);
|
|
|
|
COUNTRYCODE cntry;
|
|
|
|
cntry.country = 0;
|
|
|
|
cntry.codepage = cp_;
|
|
|
|
unsigned char *DBCSinfo = new unsigned char[12];
|
|
|
|
/* rc = */ DosQueryDBCSEnv(12, &cntry, (char*) DBCSinfo);
|
|
|
|
// if (rc != NO_ERROR)
|
|
|
|
// exit(rc);
|
|
|
|
for (int j = 1; j < 12; j += 2)
|
|
|
|
DBCSinfo[j]++;
|
|
|
|
unsigned char i = 0;
|
|
|
|
bool isLeadByte = false;
|
|
|
|
while (*DBCSinfo != 0) {
|
|
|
|
if (i == *DBCSinfo) {
|
|
|
|
isLeadByte = !isLeadByte;
|
|
|
|
DBCSinfo++;
|
|
|
|
}
|
|
|
|
leadbyte[i++] = isLeadByte;
|
|
|
|
}
|
|
|
|
initialized = true;
|
|
|
|
}
|
|
|
|
string::iterator lit = p.begin();
|
|
|
|
string::iterator end = p.end();
|
|
|
|
for (; lit < end; ++lit) {
|
|
|
|
if (leadbyte[(*lit)])
|
|
|
|
lit += 2;
|
|
|
|
if ((*lit) == '\\')
|
|
|
|
(*lit) = '/';
|
|
|
|
}
|
|
|
|
p = subst(p, "//", "/");
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2001-10-08 14:09:06 +00:00
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
string external_path(string const & p)
|
|
|
|
{
|
2001-05-17 15:11:01 +00:00
|
|
|
return p;
|
|
|
|
}
|
2001-10-04 09:57:02 +00:00
|
|
|
|
2001-10-08 14:09:06 +00:00
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
string internal_path(string const & p)
|
|
|
|
{
|
2001-10-04 09:57:02 +00:00
|
|
|
return p;
|
|
|
|
}
|
2001-10-08 14:09:06 +00:00
|
|
|
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
bool is_absolute_path(string const & p)
|
2001-10-08 14:09:06 +00:00
|
|
|
{
|
|
|
|
return (p.length() > 1
|
|
|
|
&& isalpha(static_cast<unsigned char>(p[0]))
|
|
|
|
&& p[1] == ':');
|
|
|
|
}
|
2002-02-08 14:32:17 +00:00
|
|
|
|
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
// returns a string suitable to be passed to popen when
|
|
|
|
// reading a pipe
|
|
|
|
char const * popen_read_mode()
|
2002-02-08 14:32:17 +00:00
|
|
|
{
|
|
|
|
return "r";
|
|
|
|
}
|
2002-09-23 16:03:11 +00:00
|
|
|
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
string binpath()
|
2002-09-23 16:03:11 +00:00
|
|
|
{
|
2003-02-10 10:22:05 +00:00
|
|
|
return binpath_;
|
2002-09-23 16:03:11 +00:00
|
|
|
}
|
2003-02-10 10:22:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
string binname()
|
|
|
|
{
|
|
|
|
return binname_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void setTmpDir(string const & p)
|
|
|
|
{
|
|
|
|
tmpdir_ = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string getTmpDir()
|
|
|
|
{
|
|
|
|
return tmpdir_;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
shell_type shell()
|
|
|
|
{
|
|
|
|
return shell_;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace os
|