3 // Various OS specific functions
7 #pragma implementation "os.h"
11 #include "support/filetools.h"
12 #define INCL_DOSFILEMGR
13 #define INCL_DOSMODULEMGR
14 #define INCL_DOSPROCESS
16 #define INCL_DOSERRORS
19 string os::binpath_ = string();
20 string os::binname_ = string();
21 string os::tmpdir_ = string();
22 os::shell_type os::_shell = os::UNIX;
23 unsigned long os::cp_ = 0;
25 void os::init(int * argc, char ** argv[]) {
26 if (argc != 0 /* This is a hack! */) {
27 _wildcard(argc, argv);
28 PTIB ptib = new TIB[1];
29 PPIB ppib = new PIB[1];
30 APIRET rc = DosGetInfoBlocks(&ptib, &ppib);
33 char* tmp = new char[256];
34 // This is the only reliable way to retrieve the executable name.
35 rc = DosQueryModuleName(ppib->pib_hmte, 256L, tmp);
40 binname_ = OnlyFilename(p);
41 binname_.erase(binname_.length()-4, string::npos);
42 binpath_ = OnlyPath(p);
44 // OS/2 cmd.exe has another use for '&'
45 string sh = OnlyFilename(GetEnvPath("EMXSHELL"));
47 // COMSPEC is set, unless user unsets
48 sh = OnlyFilename(GetEnvPath("COMSPEC"));
52 sh = lowercase(sh); // DosMapCase() is an overkill here
53 if (contains(sh, "cmd.exe")
54 || contains(sh, "4os2.exe"))
59 static bool initialized = false;
60 if (initialized) return;
62 ULONG CPList[3] = {0}, CPList_size;
63 APIRET rc = DosQueryCp(3 * sizeof(ULONG), CPList, &CPList_size);
66 // CPList[0] == process current codepage,
67 // CPList[1] == system default codepage, the rest are auxilary.
68 // Once cp_ is correctly set, you can call other routines.
72 void os::warn(string /*mesg*/) {
76 string os::current_root() {
78 ULONG drv_num, drv_map;
79 rc = DosQueryCurrentDisk(&drv_num, &drv_map);
82 char drive = 'A' + drv_num -1;
88 string::size_type os::common_path(string const &p1, string const &p2) {
89 static bool initialized = false;
97 string temp1 = slashify_path(p1);
98 string temp2 = slashify_path(p2);
99 char * tmp1 = const_cast<char*> (temp1.c_str());
100 char * tmp2 = const_cast<char*> (temp2.c_str());
101 /* rc = */ DosMapCase(p1.length(), &cntry, tmp1);
102 // if (rc != NO_ERROR)
104 /* rc = */ DosMapCase(p2.length(), &cntry, tmp2);
105 // if (rc != NO_ERROR)
107 // This algorithm works only if paths are slashified on DBCS systems.
108 string::size_type i = 0,
109 p1_len = p1.length(),
110 p2_len = p2.length();
111 while (i < p1_len && i < p2_len && tmp1[i] == tmp2[i]) ++i;
112 if ((i < p1_len && i < p2_len)
113 || (i < p1_len && tmp1[i] != '/' && i == p2_len)
114 || (i < p2_len && tmp2[i] != '/' && i == p1_len)) {
115 if (i) --i; // here was the last match
116 while (i && tmp1[i] != '/') --i;
121 string os::slashify_path(string p) {
122 static bool initialized = false;
123 static bool leadbyte[256] = {false};
128 cntry.codepage = cp_;
129 unsigned char *DBCSinfo = new unsigned char[12];
130 /* rc = */ DosQueryDBCSEnv(12, &cntry, (char*) DBCSinfo);
131 // if (rc != NO_ERROR)
133 for (int j = 1; j < 12; j += 2)
136 bool isLeadByte = false;
137 while (*DBCSinfo != 0) {
138 if (i == *DBCSinfo) {
139 isLeadByte = !isLeadByte;
142 leadbyte[i++] = isLeadByte;
146 string::iterator lit = p.begin();
147 string::iterator end = p.end();
148 for (; lit < end; ++lit) {
149 if (leadbyte[(*lit)])
154 p = subst(p, "//", "/");
158 string os::external_path(string p) {