/*#io
System ioDoc(
docCopyright("Steve Dekorte", 2002)
docLicense("BSD revised")
docObject("System")
docDescription("Contains methods related to the IoVM.")
docCategory("Core")
*/
#include "IoSystem.h"
#include "IoNumber.h"
#include "IoMessage_parser.h"
#if defined(linux)
#include <unistd.h>
#endif
#if defined(unix) || defined(__APPLE__) || defined(__NetBSD__)
#include <sys/utsname.h>
#ifdef __NetBSD__
# include <sys/param.h>
#endif
#ifndef __CYGWIN__
# include <sys/sysctl.h>
#endif
#endif
#ifdef WIN32
#include <windows.h>
static void setenv(const char *varName, const char* value, int force)
{
const char *safeValue;
char *buf;
if (!varName)
{
return;
}
if (!value)
{
safeValue = "";
}
else
{
safeValue = value;
}
// buffer for var and value plus '=' and the \0
buf = (char*)malloc(strlen(varName) + strlen(safeValue) + 2);
if (!buf)
{
return;
}
strcpy(buf, varName);
strcat(buf, "=");
strcat(buf, safeValue);
_putenv(buf);
free(buf);
}
//#define setenv(k, v, o) SetEnvironmentVariable((k), (v))
#endif
#if defined(__CYGWIN__) || defined(_WIN32)
#include <windows.h>
#endif
IoObject *IoSystem_proto(void *state)
{
IoMethodTable methodTable[] = {
{"errno", IoObject_errnoDescription},
{"exit", IoObject_exit},
{"getenv", IoObject_getenv},
{"setenv", IoObject_setenv},
{"system", IoObject_system},
//{"memorySizeOfState", IoObject_memorySizeOfState},
//{"compactState", IoObject_compactState},
{"platform", IoObject_platform},
{"platformVersion", IoObject_platformVersion},
{"sleep", IoObject_sleep},
{"activeCpus", IoObject_activeCpus},
{NULL, NULL},
};
IoObject *self = IoObject_new(state);
IoObject_addMethodTable_(self, methodTable);
IoObject_setSlot_to_(self, IOSYMBOL("version"), IONUMBER(IO_VERSION_NUMBER));
IoObject_setSlot_to_(self, IOSYMBOL("distribution"), IOSYMBOL("Io"));
IoObject_setSlot_to_(self, IOSYMBOL("type"), IOSYMBOL("System"));
return self;
}
/*
IoObject *IoObject_errno(IoObject *self, IoObject *locals, IoMessage *m)
{
return IONUMBER(errno);
}
*/
#include <stdio.h>
#include <errno.h>
IoObject *IoObject_errnoDescription(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("errno", "Returns the C errno string.")
*/
return errno ? IOSYMBOL(strerror(errno)) : IONIL(self);
}
IoObject *IoObject_exit(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("exit(optionalReturnCodeNumber)",
"Shutdown the IoState (free all objects) and return
control to the calling program (if any). ")
*/
int returnCode = 0;
if (IoMessage_argCount(m))
{
returnCode = IoMessage_locals_intArgAt_(m, locals, 0);
}
IoState_exit(IOSTATE, returnCode);
return self;
}
IoObject *IoObject_getenv(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("getenv(nameString)",
"Returns a string with the value of the environment
variable whose name is specified by nameString.")
*/
IoSymbol *key = IoMessage_locals_symbolArgAt_(m, locals, 0);
char *s = getenv(CSTRING(key));
if (!s)
{
return ((IoState *)IOSTATE)->ioNil;
}
return IoState_symbolWithCString_(IOSTATE, s);
}
IoObject *IoObject_system(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("system(aString)",
"Makes a system call and returns a Number for the return value.")
*/
IoSymbol *s = IoMessage_locals_symbolArgAt_(m, locals, 0);
int result = system(CSTRING(s));
//printf("system result = %i", result);
return IONUMBER((double)result);
}
IoObject *IoObject_memorySizeOfState(IoObject *self, IoObject *locals, IoMessage *m)
{
/*
docSlot("memorySizeOfState",
"Returns the number of bytes in the IoState
(this may not include memory allocated by C libraries).")
*/
return IONUMBER(0);
//return IONUMBER(IoState_memorySize(IOSTATE));
}
IoObject *IoObject_compactState(IoObject *self, IoObject *locals, IoMessage *m)
{
/*
docSlot("compactState",
"Attempt to compact the memory of the IoState if possible.")
*/
//IoState_compact(IOSTATE);
return self;
}
IoObject *IoObject_setenv(IoObject *self, IoObject *locals, IoMessage *m)
{
// setenv() takes different args in different implementations
IoSymbol *key = IoMessage_locals_symbolArgAt_(m, locals, 0);
IoSymbol *value = IoMessage_locals_symbolArgAt_(m, locals, 1);
setenv(CSTRING(key), CSTRING(value), 1);
return self;
}
IoObject *IoObject_platform(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("platform", "Returns a string description of the platform.")
*/
char *platform = "Unknown";
#if defined(__CYGWIN__)
platform = "cygwin";
#elif defined(_WIN32)
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx(&os);
switch(os.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
switch(os.dwMinorVersion)
{
case 0:
platform = "Windows 95";
break;
case 10:
platform = "Windows 98";
break;
case 90:
platform = "Windows ME";
break;
default:
platform = "Windows 9X";
break;
}
break;
case VER_PLATFORM_WIN32_NT:
if (os.dwMajorVersion == 3 || os.dwMajorVersion == 4)
{
platform = "Windows NT";
}
else if (os.dwMajorVersion == 5)
{
switch(os.dwMinorVersion)
{
case 0:
platform = "Windows 2000";
break;
case 1:
platform = "Windows XP";
break;
default:
platform = "Windows";
break;
}
}
break;
}
#elif defined(unix) || defined(__APPLE__) || defined(__NetBSD__)
/* Why Apple and NetBSD don't define 'unix' I'll never know. */
struct utsname os;
int ret = uname(&os);
if (ret == 0)
{
platform = os.sysname;
}
#endif
return IoState_symbolWithCString_(self->state, platform);
}
IoObject *IoObject_platformVersion(IoObject *self, IoObject *locals, IoMessage *m)
{
char platformVersion[256];
#if defined(_WIN32)
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
GetVersionEx(&os);
snprintf(platformVersion, sizeof(platformVersion) - 1, "%d.%d",
os.dwMajorVersion, os.dwMinorVersion);
#elif defined(unix) || defined(__APPLE__) || defined(__NetBSD__)
/* Why Apple and NetBSD don't define 'unix' I'll never know. */
struct utsname os;
int ret = uname(&os);
if (ret == 0)
{
snprintf(platformVersion, sizeof(platformVersion) - 1, os.release);
}
#endif
return IoState_symbolWithCString_(self->state, platformVersion);
}
IoObject *IoObject_activeCpus(IoObject *self, IoObject *locals, IoMessage *m)
{
/*#io
docSlot("activeCpus", "Returns the number of active CPUs.")
*/
int cpus = 1;
#if defined(CTL_HW)
int mib[2];
size_t len = sizeof(cpus);
mib[0] = CTL_HW;
#if defined(HW_AVAILCPU)
mib[1] = HW_AVAILCPU;
#elif defined(HW_NCPU)
mib[1] = HW_NCPU;
#else
#error
#endif
sysctl(mib, 2, &cpus, &len, NULL, 0);
#elif defined(_SC_NPROCESSORS_ONLN)
cpus = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(_SC_NPROC_ONLN)
cpus = sysconf(_SC_NPROC_ONLN);
#elif defined(WIN32)
SYSTEM_INFO si;
GetSystemInfo(&si);
cpus = si.dwNumberOfProcessors;
#else
#error
#endif
return IONUMBER(cpus);
}
#include "PortableUsleep.h"
IoObject *IoObject_sleep(IoObject *self, IoObject *locals, IoMessage *m)
{
double seconds = IoMessage_locals_doubleArgAt_(m, locals, 0);
unsigned int microseconds = (seconds * 1000000);
usleep(microseconds);
return self;
}
/*#io
docSlot("version", "Returns a version number for Io.")
*/
/*#io
docSlot("distribution", "Returns the Io distribution name as a string.")
*/
syntax highlighted by Code2HTML, v. 0.9.1