Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifdef HAVE_CONFIG_H
00040 #include <config.h>
00041 #endif
00042
00043 #include <cctype>
00044 #include <cstdlib>
00045 #include <cstring>
00046
00047 #include <string>
00048
00049 #include <sys/types.h>
00050 #include <unistd.h>
00051
00052 #include "progname.h"
00053
00054 #include "file-ops.h"
00055 #include "lo-error.h"
00056 #include "lo-sysdep.h"
00057 #include "lo-utils.h"
00058 #include "oct-env.h"
00059 #include "oct-passwd.h"
00060 #include "oct-syscalls.h"
00061 #include "singleton-cleanup.h"
00062
00063 octave_env::octave_env (void)
00064 : follow_symbolic_links (true), verbatim_pwd (true),
00065 current_directory (), prog_name (), prog_invocation_name (),
00066 user_name (), host_name ()
00067 {
00068
00069 do_getcwd ();
00070
00071
00072 do_get_user_name ();
00073
00074 do_get_host_name ();
00075 }
00076
00077 octave_env *octave_env::instance = 0;
00078
00079 bool
00080 octave_env::instance_ok (void)
00081 {
00082 bool retval = true;
00083
00084 if (! instance)
00085 {
00086 instance = new octave_env ();
00087
00088 if (instance)
00089 singleton_cleanup_list::add (cleanup_instance);
00090 }
00091
00092 if (! instance)
00093 {
00094 (*current_liboctave_error_handler)
00095 ("unable to create current working directory object!");
00096
00097 retval = false;
00098 }
00099
00100 return retval;
00101 }
00102
00103 std::string
00104 octave_env::polite_directory_format (const std::string& name)
00105 {
00106 return (instance_ok ())
00107 ? instance->do_polite_directory_format (name) : std::string ();
00108 }
00109
00110 bool
00111 octave_env::absolute_pathname (const std::string& s)
00112 {
00113 return (instance_ok ())
00114 ? instance->do_absolute_pathname (s) : false;
00115 }
00116
00117 bool
00118 octave_env::rooted_relative_pathname (const std::string& s)
00119 {
00120 return (instance_ok ())
00121 ? instance->do_rooted_relative_pathname (s) : false;
00122 }
00123
00124 std::string
00125 octave_env::base_pathname (const std::string& s)
00126 {
00127 return (instance_ok ())
00128 ? instance->do_base_pathname (s) : std::string ();
00129 }
00130
00131 std::string
00132 octave_env::make_absolute (const std::string& s, const std::string& dot_path)
00133 {
00134 return (instance_ok ())
00135 ? instance->do_make_absolute (s, dot_path) : std::string ();
00136 }
00137
00138 std::string
00139 octave_env::get_current_directory ()
00140 {
00141 return (instance_ok ())
00142 ? instance->do_getcwd () : std::string ();
00143 }
00144
00145 std::string
00146 octave_env::get_home_directory ()
00147 {
00148 return (instance_ok ())
00149 ? instance->do_get_home_directory () : std::string ();
00150 }
00151
00152 std::string
00153 octave_env::get_program_name (void)
00154 {
00155 return (instance_ok ())
00156 ? instance->prog_name : std::string ();
00157 }
00158
00159 std::string
00160 octave_env::get_program_invocation_name (void)
00161 {
00162 return (instance_ok ())
00163 ? instance->prog_invocation_name : std::string ();
00164 }
00165
00166 void
00167 octave_env::set_program_name (const std::string& s)
00168 {
00169 if (instance_ok ())
00170 instance->do_set_program_name (s);
00171 }
00172
00173 std::string
00174 octave_env::get_user_name (void)
00175 {
00176 return (instance_ok ())
00177 ? instance->do_get_user_name () : std::string ();
00178 }
00179
00180 std::string
00181 octave_env::get_host_name (void)
00182 {
00183 return (instance_ok ())
00184 ? instance->do_get_host_name () : std::string ();
00185 }
00186
00187
00188
00189
00190
00191 std::string
00192 octave_env::getenv (const std::string& name)
00193 {
00194 return (instance_ok ())
00195 ? instance->do_getenv (name) : std::string ();
00196 }
00197
00198 void
00199 octave_env::putenv (const std::string& name, const std::string& value)
00200 {
00201 octave_putenv (name, value);
00202 }
00203
00204 bool
00205 octave_env::have_x11_display (void)
00206 {
00207 std::string display = getenv ("DISPLAY");
00208
00209 return ! display.empty ();
00210 }
00211
00212 bool
00213 octave_env::chdir (const std::string& newdir)
00214 {
00215 return (instance_ok ())
00216 ? instance->do_chdir (newdir) : false;
00217 }
00218
00219 void
00220 octave_env::do_set_program_name (const std::string& s) const
00221 {
00222
00223 ::set_program_name (s.c_str ());
00224
00225
00226 prog_invocation_name = program_name;
00227
00228 size_t pos
00229 = prog_invocation_name.find_last_of (file_ops::dir_sep_chars ());
00230
00231
00232 prog_name = (pos == std::string::npos)
00233 ? prog_invocation_name : prog_invocation_name.substr (pos+1);
00234 }
00235
00236
00237
00238
00239 std::string
00240 octave_env::do_polite_directory_format (const std::string& name) const
00241 {
00242 std::string retval;
00243
00244 std::string home_dir = do_get_home_directory ();
00245
00246 size_t len = home_dir.length ();
00247
00248 if (len > 1 && home_dir == name.substr (0, len)
00249 && (name.length () == len || file_ops::is_dir_sep (name[len])))
00250 {
00251 retval = "~";
00252 retval.append (name.substr (len));
00253 }
00254 else
00255 retval = name;
00256
00257 return retval;
00258 }
00259
00260 bool
00261 octave_env::do_absolute_pathname (const std::string& s) const
00262 {
00263 size_t len = s.length ();
00264
00265 if (len == 0)
00266 return false;
00267
00268 if (file_ops::is_dir_sep (s[0]))
00269 return true;
00270
00271 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
00272 if ((len == 2 && isalpha (s[0]) && s[1] == ':')
00273 || (len > 2 && isalpha (s[0]) && s[1] == ':'
00274 && file_ops::is_dir_sep (s[2])))
00275 return true;
00276 #endif
00277
00278 return false;
00279 }
00280
00281 bool
00282 octave_env::do_rooted_relative_pathname (const std::string& s) const
00283 {
00284 size_t len = s.length ();
00285
00286 if (len == 0)
00287 return false;
00288
00289 if (len == 1 && s[0] == '.')
00290 return true;
00291
00292 if (len > 1 && s[0] == '.' && file_ops::is_dir_sep (s[1]))
00293 return true;
00294
00295 if (len == 2 && s[0] == '.' && s[1] == '.')
00296 return true;
00297
00298 if (len > 2 && s[0] == '.' && s[1] == '.' && file_ops::is_dir_sep (s[2]))
00299 return true;
00300
00301 return false;
00302 }
00303
00304
00305
00306
00307
00308 std::string
00309 octave_env::do_base_pathname (const std::string& s) const
00310 {
00311 if (! (do_absolute_pathname (s) || do_rooted_relative_pathname (s)))
00312 return s;
00313
00314 size_t pos = s.find_last_of (file_ops::dir_sep_chars ());
00315
00316 if (pos == std::string::npos)
00317 return s;
00318 else
00319 return s.substr (pos+1);
00320 }
00321
00322
00323
00324
00325 std::string
00326 octave_env::do_make_absolute (const std::string& s,
00327 const std::string& dot_path) const
00328 {
00329 if (dot_path.empty () || s.empty () || do_absolute_pathname (s))
00330 return s;
00331
00332 std::string current_dir = dot_path;
00333
00334 if (current_dir.empty ())
00335 current_dir = do_getcwd ();
00336
00337 size_t pos = current_dir.length () - 1;
00338
00339 if (! file_ops::is_dir_sep (current_dir[pos]))
00340 current_dir.append (file_ops::dir_sep_str ());
00341
00342
00343
00344 size_t i = 0;
00345 size_t slen = s.length ();
00346
00347 while (i < slen)
00348 {
00349 if (s[i] == '.')
00350 {
00351 if (i + 1 == slen)
00352 return current_dir;
00353
00354 if (file_ops::is_dir_sep (s[i+1]))
00355 {
00356 i += 2;
00357 continue;
00358 }
00359
00360 if (s[i+1] == '.'
00361 && (i + 2 == slen || file_ops::is_dir_sep (s[i+2])))
00362 {
00363 i += 2;
00364
00365 if (i != slen)
00366 i++;
00367
00368 pathname_backup (current_dir, 1);
00369
00370 continue;
00371 }
00372 }
00373
00374 size_t tmp = s.find_first_of (file_ops::dir_sep_chars (), i);
00375
00376 if (tmp == std::string::npos)
00377 {
00378 current_dir.append (s, i, tmp-i);
00379 break;
00380 }
00381 else
00382 {
00383 current_dir.append (s, i, tmp-i+1);
00384 i = tmp + 1;
00385 }
00386 }
00387
00388 return current_dir;
00389 }
00390
00391
00392
00393 std::string
00394 octave_env::do_getcwd () const
00395 {
00396 if (! follow_symbolic_links)
00397 current_directory = "";
00398
00399 if (verbatim_pwd || current_directory.empty ())
00400 current_directory = ::octave_getcwd ();
00401
00402 return current_directory;
00403 }
00404
00405
00406
00407
00408 std::string
00409 octave_env::do_get_home_directory (void) const
00410 {
00411 std::string hd = do_getenv ("HOME");
00412
00413 #if defined (__MINGW32__) || defined (_MSC_VER)
00414
00415 if (hd.empty ())
00416 {
00417 std::string drv = do_getenv ("HOMEDRIVE");
00418 if (drv.empty ())
00419 hd = do_getenv ("HOMEPATH");
00420 else
00421 hd = drv + do_getenv ("HOMEPATH");
00422 }
00423 #endif
00424
00425 if (hd.empty ())
00426 {
00427 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00428
00429 hd = pw ? pw.dir () : std::string (file_ops::dir_sep_str ());
00430 }
00431
00432 return hd;
00433 }
00434
00435 std::string
00436 octave_env::do_get_user_name (void) const
00437 {
00438 if (user_name.empty ())
00439 {
00440 octave_passwd pw = octave_passwd::getpwuid (octave_syscalls::getuid ());
00441
00442 user_name = pw ? pw.name () : std::string ("unknown");
00443 }
00444
00445 return user_name;
00446 }
00447
00448 std::string
00449 octave_env::do_get_host_name (void) const
00450 {
00451 if (host_name.empty ())
00452 {
00453 char hostname[1024];
00454
00455 int status = gnulib::gethostname (hostname, 1023);
00456
00457 host_name = (status < 0) ? "unknown" : hostname;
00458 }
00459
00460 return host_name;
00461 }
00462
00463 std::string
00464 octave_env::do_getenv (const std::string& name) const
00465 {
00466 char *value = ::getenv (name.c_str ());
00467
00468 return value ? value : "";
00469 }
00470
00471
00472
00473
00474 bool
00475 octave_env::do_chdir (const std::string& newdir)
00476 {
00477 bool retval = false;
00478
00479 std::string tmp;
00480
00481 if (follow_symbolic_links)
00482 {
00483 if (current_directory.empty ())
00484 do_getcwd ();
00485
00486 if (current_directory.empty ())
00487 tmp = newdir;
00488 else
00489 tmp = do_make_absolute (newdir, current_directory);
00490
00491
00492
00493 size_t len = tmp.length ();
00494
00495 if (len > 1)
00496 {
00497 if (file_ops::is_dir_sep (tmp[--len]))
00498 tmp.resize (len);
00499 }
00500
00501 if (! ::octave_chdir (tmp))
00502 {
00503 current_directory = tmp;
00504 retval = true;
00505 }
00506 }
00507 else
00508 retval = (! ::octave_chdir (newdir));
00509
00510 return retval;
00511 }
00512
00513
00514
00515 void
00516 octave_env::pathname_backup (std::string& path, int n) const
00517 {
00518 if (path.empty ())
00519 return;
00520
00521 size_t i = path.length () - 1;
00522
00523 while (n--)
00524 {
00525 while (file_ops::is_dir_sep (path[i]) && i > 0)
00526 i--;
00527
00528 while (! file_ops::is_dir_sep (path[i]) && i > 0)
00529 i--;
00530
00531 i++;
00532 }
00533
00534 path.resize (i);
00535 }
00536
00537 void
00538 octave_env::error (int err_num) const
00539 {
00540 (*current_liboctave_error_handler) ("%s", gnulib::strerror (err_num));
00541 }
00542
00543 void
00544 octave_env::error (const std::string& s) const
00545 {
00546 (*current_liboctave_error_handler) ("%s", s.c_str ());
00547 }