704c883bf5364519dc9494e936fe7be7a0b435fe
[feisty_meow.git] / nucleus / library / basis / environment.cpp
1 //////////////
2 // Name   : environment
3 // Author : Chris Koeritz
4 //////////////
5 // Copyright (c) 1994-$now By Author.  This program is free software; you can
6 // redistribute it and/or modify it under the terms of the GNU General Public
7 // License as published by the Free Software Foundation:
8 //     http://www.gnu.org/licenses/gpl.html
9 // or under the terms of the GNU Library license:
10 //     http://www.gnu.org/licenses/lgpl.html
11 // at your preference.  Those licenses describe your legal rights to this
12 // software, and no other rights or warranties apply.
13 // Please send updates for this code to: fred@gruntose.com -- Thanks, fred.
14 //////////////
15
16 #include "environment.h"
17
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #ifndef _MSC_VER
21   #include <unistd.h>
22   #include <sys/times.h>
23 #endif
24 /*
25 #ifdef _MSC_VER
26   #define _WINSOCKAPI_  // make windows.h happy about winsock.
27   // winsock support...
28 //  #undef FD_SETSIZE
29 //  #define FD_SETSIZE 1000
30     // if you don't set this, you can only select on a default of 64 sockets.
31   #include <winsock2.h>
32   #include <windows.h>
33   #include <mmsystem.h>
34 #endif
35 */
36
37 namespace basis {
38
39 astring environment::TMP()
40 {
41   const static astring TMP_VARIABLE_NAME("TMP");
42   astring to_return = get(TMP_VARIABLE_NAME);
43   if (!to_return) {
44     // they did not see fit to set this in the environment.  let's make something up.
45 #ifdef __WIN32__
46     // windows default does not necessarily exist.
47     to_return = "c:/tmp";
48 #else
49     // most reasonable OSes have a /tmp directory.
50     to_return = "/tmp";
51 #endif
52     if (!!to_return) set("TMP", to_return);
53   }
54   return to_return;
55 }
56
57 astring environment::get(const astring &variable_name)
58 {
59 #ifdef _MSC_VER
60   char *value = getenv(variable_name.upper().observe());
61     // dos & os/2 require upper case for the name, so we just do it that way.
62 #else
63   char *value = getenv(variable_name.observe());
64     // reasonable OSes support mixed-case environment variables.
65 #endif
66   astring to_return;
67   if (value)
68     to_return = astring(value);
69   return to_return;
70 }
71
72 bool environment::set(const astring &variable_name, const astring &value)
73 {
74   int ret = 0;
75 #ifdef _MSC_VER
76   astring assignment = variable_name + "=" + value;
77   ret = _putenv(assignment.s());
78 #else
79   ret = setenv(variable_name.s(), value.s(), true);
80 #endif
81   return !ret;
82 }
83
84 basis::un_int environment::system_uptime()
85 {
86 #ifdef _MSC_VER
87   return timeGetTime();
88 #else
89   static clock_t __ctps = sysconf(_SC_CLK_TCK);  // clock ticks per second.
90   static const double __multiplier = 1000.0 / double(__ctps);
91     // the multiplier gives us our full range for the tick counter.
92
93   // read uptime info from the OS.
94   tms uptime;
95   basis::un_int real_ticks = times(&uptime);
96
97   // now turn this into the number of milliseconds.
98   double ticks_up = (double)real_ticks;
99   ticks_up = ticks_up * __multiplier;  // convert to time here.
100
101   // we use the previous version of this calculation, which expected a basis::u_int
102   // to double conversion to provide a modulo operation rather than just leaving
103   // the basis::un_int at its maximum value (2^32-1).  however, that expectation is not
104   // guaranteed on some platforms (e.g., ARM processor with floating point
105   // emulation) and thus it becomes a bug around 49 days and 17 hours into
106   // OS uptime because the value gets stuck at 2^32-1 and never rolls over.
107   return basis::un_int(ticks_up);
108 #endif
109 }
110
111 } //namespace.
112