mirror of https://github.com/lukechilds/node.git
18 changed files with 130 additions and 1952 deletions
@ -1,49 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef NODE_PLATFORM_H_ |
|||
#define NODE_PLATFORM_H_ |
|||
|
|||
#include <v8.h> |
|||
|
|||
namespace node { |
|||
|
|||
class Platform { |
|||
public: |
|||
static char** SetupArgs(int argc, char *argv[]); |
|||
static void SetProcessTitle(char *title); |
|||
static const char* GetProcessTitle(int *len); |
|||
|
|||
static int GetMemory(size_t *rss); |
|||
static int GetCPUInfo(v8::Local<v8::Array> *cpus); |
|||
static double GetUptime(bool adjusted = false) |
|||
{ |
|||
return adjusted ? GetUptimeImpl() - prog_start_time : GetUptimeImpl(); |
|||
} |
|||
static v8::Handle<v8::Value> GetInterfaceAddresses(); |
|||
private: |
|||
static double GetUptimeImpl(); |
|||
static double prog_start_time; |
|||
}; |
|||
|
|||
|
|||
} // namespace node
|
|||
#endif // NODE_PLATFORM_H_
|
@ -1,227 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
#include <v8.h> |
|||
|
|||
#include <mach/task.h> |
|||
#include <mach/mach.h> |
|||
#include <mach/mach_host.h> |
|||
#include <limits.h> /* PATH_MAX */ |
|||
|
|||
#include <unistd.h> // sysconf |
|||
#include <sys/param.h> |
|||
#include <sys/sysctl.h> |
|||
#include <time.h> |
|||
#include <sys/socket.h> |
|||
#include <net/if.h> |
|||
#include <netinet/in.h> |
|||
#include <arpa/inet.h> |
|||
#include <ifaddrs.h> |
|||
|
|||
#include <node_vars.h> |
|||
#define process_title NODE_VAR(process_title) |
|||
|
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
process_title = argc ? strdup(argv[0]) : NULL; |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
// Platform::SetProcessTitle implemented in platform_darwin_proctitle.cc
|
|||
} // namespace node
|
|||
#include "platform_darwin_proctitle.cc" |
|||
namespace node { |
|||
|
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
if (process_title) { |
|||
*len = strlen(process_title); |
|||
return process_title; |
|||
} |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
|
|||
// Researched by Tim Becker and Michael Knight
|
|||
// http://blog.kuriositaet.de/?p=257
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
struct task_basic_info t_info; |
|||
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; |
|||
|
|||
int r = task_info(mach_task_self(), |
|||
TASK_BASIC_INFO, |
|||
(task_info_t)&t_info, |
|||
&t_info_count); |
|||
|
|||
if (r != KERN_SUCCESS) return -1; |
|||
|
|||
*rss = t_info.resident_size; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
Local<Object> cpuinfo; |
|||
Local<Object> cputimes; |
|||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), |
|||
multiplier = ((uint64_t)1000L / ticks); |
|||
char model[512]; |
|||
uint64_t cpuspeed; |
|||
size_t size; |
|||
|
|||
size = sizeof(model); |
|||
if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
size = sizeof(cpuspeed); |
|||
if (sysctlbyname("hw.cpufrequency", &cpuspeed, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
natural_t numcpus; |
|||
mach_msg_type_number_t count; |
|||
processor_cpu_load_info_data_t *info; |
|||
if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, |
|||
reinterpret_cast<processor_info_array_t*>(&info), |
|||
&count) != KERN_SUCCESS) { |
|||
return -1; |
|||
} |
|||
*cpus = Array::New(numcpus); |
|||
for (unsigned int i = 0; i < numcpus; i++) { |
|||
cpuinfo = Object::New(); |
|||
cputimes = Object::New(); |
|||
cputimes->Set(String::New("user"), |
|||
Number::New((uint64_t)(info[i].cpu_ticks[0]) * multiplier)); |
|||
cputimes->Set(String::New("nice"), |
|||
Number::New((uint64_t)(info[i].cpu_ticks[3]) * multiplier)); |
|||
cputimes->Set(String::New("sys"), |
|||
Number::New((uint64_t)(info[i].cpu_ticks[1]) * multiplier)); |
|||
cputimes->Set(String::New("idle"), |
|||
Number::New((uint64_t)(info[i].cpu_ticks[2]) * multiplier)); |
|||
cputimes->Set(String::New("irq"), Number::New(0)); |
|||
|
|||
cpuinfo->Set(String::New("model"), String::New(model)); |
|||
cpuinfo->Set(String::New("speed"), Number::New(cpuspeed/1000000)); |
|||
|
|||
cpuinfo->Set(String::New("times"), cputimes); |
|||
(*cpus)->Set(i, cpuinfo); |
|||
} |
|||
vm_deallocate(mach_task_self(), (vm_address_t)info, count); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
time_t now; |
|||
struct timeval info; |
|||
size_t size = sizeof(info); |
|||
static int which[] = {CTL_KERN, KERN_BOOTTIME}; |
|||
|
|||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
now = time(NULL); |
|||
|
|||
return static_cast<double>(now - info.tv_sec); |
|||
} |
|||
|
|||
|
|||
v8::Handle<v8::Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
struct ::ifaddrs *addrs, *ent; |
|||
struct ::sockaddr_in *in4; |
|||
struct ::sockaddr_in6 *in6; |
|||
char ip[INET6_ADDRSTRLEN]; |
|||
Local<Object> ret, o; |
|||
Local<String> name, ipaddr, family; |
|||
Local<Array> ifarr; |
|||
|
|||
if (getifaddrs(&addrs) != 0) { |
|||
return ThrowException(ErrnoException(errno, "getifaddrs")); |
|||
} |
|||
|
|||
ret = Object::New(); |
|||
|
|||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) { |
|||
bzero(&ip, sizeof (ip)); |
|||
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { |
|||
continue; |
|||
} |
|||
|
|||
if (ent->ifa_addr == NULL) { |
|||
continue; |
|||
} |
|||
|
|||
/*
|
|||
* On Mac OS X getifaddrs returns information related to Mac Addresses for |
|||
* various devices, such as firewire, etc. These are not relevant here. |
|||
*/ |
|||
if (ent->ifa_addr->sa_family == AF_LINK) |
|||
continue; |
|||
|
|||
name = String::New(ent->ifa_name); |
|||
if (ret->Has(name)) { |
|||
ifarr = Local<Array>::Cast(ret->Get(name)); |
|||
} else { |
|||
ifarr = Array::New(); |
|||
ret->Set(name, ifarr); |
|||
} |
|||
|
|||
if (ent->ifa_addr->sa_family == AF_INET6) { |
|||
in6 = (struct sockaddr_in6 *)ent->ifa_addr; |
|||
inet_ntop(AF_INET6, &(in6->sin6_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv6"); |
|||
} else if (ent->ifa_addr->sa_family == AF_INET) { |
|||
in4 = (struct sockaddr_in *)ent->ifa_addr; |
|||
inet_ntop(AF_INET, &(in4->sin_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv4"); |
|||
} else { |
|||
(void) strlcpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN); |
|||
family = String::New("<unknown>"); |
|||
} |
|||
|
|||
o = Object::New(); |
|||
o->Set(String::New("address"), String::New(ip)); |
|||
o->Set(String::New("family"), family); |
|||
o->Set(String::New("internal"), ent->ifa_flags & IFF_LOOPBACK ? |
|||
True() : False()); |
|||
|
|||
ifarr->Set(ifarr->Length(), o); |
|||
|
|||
} |
|||
|
|||
freeifaddrs(addrs); |
|||
|
|||
return scope.Close(ret); |
|||
} |
|||
|
|||
} // namespace node
|
@ -1,146 +0,0 @@ |
|||
// Copyright 2010, Google Inc.
|
|||
// All rights reserved.
|
|||
//
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following disclaimer
|
|||
// in the documentation and/or other materials provided with the
|
|||
// distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived from
|
|||
// this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//
|
|||
// This code emanates from the Chromium project:
|
|||
// http://src.chromium.org/viewvc/chrome/trunk/src/base/mac_util.mm
|
|||
|
|||
#include <CoreFoundation/CoreFoundation.h> |
|||
#include <Carbon/Carbon.h> // Oh noes! See discussion blow at GetCurrentProcess |
|||
#ifndef NDEBUG |
|||
#include <err.h> |
|||
#endif |
|||
|
|||
namespace node { |
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
static int symbol_lookup_status = 0; // 1=ok, 2=unavailable
|
|||
if (symbol_lookup_status == 2) { |
|||
// feature is unavailable
|
|||
return; |
|||
} |
|||
|
|||
if (process_title) free(process_title); |
|||
process_title = strdup(title); |
|||
|
|||
// Warning: here be dragons! This is SPI reverse-engineered from WebKit's
|
|||
// plugin host, and could break at any time (although realistically it's only
|
|||
// likely to break in a new major release).
|
|||
// When 10.7 is available, check that this still works, and update this
|
|||
// comment for 10.8.
|
|||
|
|||
// Private CFType used in these LaunchServices calls.
|
|||
typedef CFTypeRef PrivateLSASN; |
|||
typedef PrivateLSASN (*LSGetCurrentApplicationASNType)(); |
|||
typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN, |
|||
CFStringRef, |
|||
CFStringRef, |
|||
CFDictionaryRef*); |
|||
|
|||
static LSGetCurrentApplicationASNType ls_get_current_application_asn_func = |
|||
NULL; |
|||
static LSSetApplicationInformationItemType |
|||
ls_set_application_information_item_func = NULL; |
|||
static CFStringRef ls_display_name_key = NULL; |
|||
if (!symbol_lookup_status) { |
|||
CFBundleRef launch_services_bundle = |
|||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices")); |
|||
if (!launch_services_bundle) { |
|||
#ifndef NDEBUG |
|||
warnx("failed to look up LaunchServices bundle"); |
|||
#endif |
|||
symbol_lookup_status = 2; |
|||
return; |
|||
} |
|||
|
|||
ls_get_current_application_asn_func = |
|||
reinterpret_cast<LSGetCurrentApplicationASNType>( |
|||
CFBundleGetFunctionPointerForName( |
|||
launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN"))); |
|||
if (!ls_get_current_application_asn_func) { |
|||
#ifndef NDEBUG |
|||
warnx("could not find _LSGetCurrentApplicationASN"); |
|||
#endif |
|||
symbol_lookup_status = 2; |
|||
return; |
|||
} |
|||
|
|||
ls_set_application_information_item_func = |
|||
reinterpret_cast<LSSetApplicationInformationItemType>( |
|||
CFBundleGetFunctionPointerForName( |
|||
launch_services_bundle, |
|||
CFSTR("_LSSetApplicationInformationItem"))); |
|||
if (!ls_set_application_information_item_func) { |
|||
#ifndef NDEBUG |
|||
warnx("Could not find _LSSetApplicationInformationItem"); |
|||
#endif |
|||
symbol_lookup_status = 2; |
|||
return; |
|||
} |
|||
|
|||
const CFStringRef* key_pointer = reinterpret_cast<const CFStringRef*>( |
|||
CFBundleGetDataPointerForName(launch_services_bundle, |
|||
CFSTR("_kLSDisplayNameKey"))); |
|||
ls_display_name_key = key_pointer ? *key_pointer : NULL; |
|||
if (!ls_display_name_key) { |
|||
#ifndef NDEBUG |
|||
warnx("Could not find _kLSDisplayNameKey"); |
|||
#endif |
|||
symbol_lookup_status = 2; |
|||
return; |
|||
} |
|||
|
|||
// Internally, this call relies on the Mach ports that are started up by the
|
|||
// Carbon Process Manager. In debug builds this usually happens due to how
|
|||
// the logging layers are started up; but in release, it isn't started in as
|
|||
// much of a defined order. So if the symbols had to be loaded, go ahead
|
|||
// and force a call to make sure the manager has been initialized and hence
|
|||
// the ports are opened.
|
|||
ProcessSerialNumber psn; |
|||
GetCurrentProcess(&psn); |
|||
symbol_lookup_status = 1; // 1=ok
|
|||
} |
|||
|
|||
PrivateLSASN asn = ls_get_current_application_asn_func(); |
|||
// Constant used by WebKit; what exactly it means is unknown.
|
|||
const int magic_session_constant = -2; |
|||
CFStringRef process_name = |
|||
CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8); |
|||
OSErr err = |
|||
ls_set_application_information_item_func(magic_session_constant, asn, |
|||
ls_display_name_key, |
|||
process_name, |
|||
NULL /* optional out param */); |
|||
#ifndef NDEBUG |
|||
if (err) { |
|||
warnx("Call LSSetApplicationInformationItem failed"); |
|||
} |
|||
#endif |
|||
} |
|||
|
|||
} // namespace node
|
@ -1,178 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
#include <v8.h> |
|||
|
|||
#include <stdlib.h> |
|||
#include <kvm.h> |
|||
#include <sys/param.h> |
|||
#include <sys/sysctl.h> |
|||
#include <sys/user.h> |
|||
#include <sys/dkstat.h> |
|||
#include <vm/vm_param.h> |
|||
#include <string.h> |
|||
#include <paths.h> |
|||
#include <fcntl.h> |
|||
#include <unistd.h> |
|||
#include <time.h> |
|||
|
|||
#include <node_vars.h> |
|||
#define process_title NODE_VAR(process_title) |
|||
|
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
process_title = argc ? strdup(argv[0]) : NULL; |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
if (process_title) free(process_title); |
|||
process_title = strdup(title); |
|||
setproctitle(title); |
|||
} |
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
if (process_title) { |
|||
*len = strlen(process_title); |
|||
return process_title; |
|||
} |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
kvm_t *kd = NULL; |
|||
struct kinfo_proc *kinfo = NULL; |
|||
pid_t pid; |
|||
int nprocs; |
|||
size_t page_size = getpagesize(); |
|||
|
|||
pid = getpid(); |
|||
|
|||
kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); |
|||
if (kd == NULL) goto error; |
|||
|
|||
kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); |
|||
if (kinfo == NULL) goto error; |
|||
|
|||
*rss = kinfo->ki_rssize * page_size; |
|||
|
|||
kvm_close(kd); |
|||
|
|||
return 0; |
|||
|
|||
error: |
|||
if (kd) kvm_close(kd); |
|||
return -1; |
|||
} |
|||
|
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
Local<Object> cpuinfo; |
|||
Local<Object> cputimes; |
|||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), |
|||
multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus, |
|||
cur = 0; |
|||
char model[512]; |
|||
int numcpus; |
|||
size_t size; |
|||
|
|||
size = sizeof(model); |
|||
if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
size = sizeof(numcpus); |
|||
if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
*cpus = Array::New(numcpus); |
|||
|
|||
size = sizeof(cpuspeed); |
|||
if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
// kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of ncpu
|
|||
size = sizeof(maxcpus); |
|||
if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
size = maxcpus * CPUSTATES * sizeof(long); |
|||
long cp_times[size]; |
|||
if (sysctlbyname("kern.cp_times", &cp_times, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
for (int i = 0; i < numcpus; i++) { |
|||
cpuinfo = Object::New(); |
|||
cputimes = Object::New(); |
|||
cputimes->Set(String::New("user"), |
|||
Number::New((uint64_t)(cp_times[CP_USER+cur]) * multiplier)); |
|||
cputimes->Set(String::New("nice"), |
|||
Number::New((uint64_t)(cp_times[CP_NICE+cur]) * multiplier)); |
|||
cputimes->Set(String::New("sys"), |
|||
Number::New((uint64_t)(cp_times[CP_SYS+cur]) * multiplier)); |
|||
cputimes->Set(String::New("idle"), |
|||
Number::New((uint64_t)(cp_times[CP_IDLE+cur]) * multiplier)); |
|||
cputimes->Set(String::New("irq"), |
|||
Number::New((uint64_t)(cp_times[CP_INTR+cur]) * multiplier)); |
|||
|
|||
cpuinfo->Set(String::New("model"), String::New(model)); |
|||
cpuinfo->Set(String::New("speed"), Number::New(cpuspeed)); |
|||
|
|||
cpuinfo->Set(String::New("times"), cputimes); |
|||
(*cpus)->Set(i, cpuinfo); |
|||
cur+=CPUSTATES; |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
time_t now; |
|||
struct timeval info; |
|||
size_t size = sizeof(info); |
|||
static int which[] = {CTL_KERN, KERN_BOOTTIME}; |
|||
|
|||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
now = time(NULL); |
|||
|
|||
return static_cast<double>(now - info.tv_sec); |
|||
} |
|||
|
|||
|
|||
Handle<Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
return scope.Close(Object::New()); |
|||
} |
|||
|
|||
} // namespace node
|
@ -1,394 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
#include <v8.h> |
|||
|
|||
#include <sys/param.h> // for MAXPATHLEN |
|||
#include <unistd.h> // getpagesize, sysconf |
|||
#include <stdio.h> // sscanf, snprintf |
|||
|
|||
/* SetProcessTitle */ |
|||
#include <sys/prctl.h> |
|||
#include <linux/prctl.h> |
|||
#include <stdlib.h> // free |
|||
#include <string.h> // strdup |
|||
|
|||
/* GetInterfaceAddresses */ |
|||
#include <arpa/inet.h> |
|||
#include <sys/types.h> |
|||
#include <ifaddrs.h> |
|||
#include <errno.h> |
|||
#include <sys/ioctl.h> |
|||
#include <net/if.h> |
|||
|
|||
#include <time.h> |
|||
|
|||
#ifndef CLOCK_MONOTONIC |
|||
# include <sys/sysinfo.h> |
|||
#endif |
|||
|
|||
#include <node_vars.h> |
|||
#define linux_process_title NODE_VAR(linux_process_title) |
|||
#define getbuf NODE_VAR(getbuf) |
|||
|
|||
extern char **environ; |
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
char **new_argv; |
|||
char **new_env; |
|||
size_t size; |
|||
int envc; |
|||
char *s; |
|||
int i; |
|||
|
|||
for (envc = 0; environ[envc]; envc++); |
|||
|
|||
s = envc ? environ[envc - 1] : argv[argc - 1]; |
|||
|
|||
linux_process_title.str = argv[0]; |
|||
linux_process_title.len = s + strlen(s) + 1 - argv[0]; |
|||
|
|||
size = linux_process_title.len; |
|||
size += (argc + 1) * sizeof(char **); |
|||
size += (envc + 1) * sizeof(char **); |
|||
|
|||
if ((s = (char *) malloc(size)) == NULL) { |
|||
linux_process_title.str = NULL; |
|||
linux_process_title.len = 0; |
|||
return argv; |
|||
} |
|||
|
|||
new_argv = (char **) s; |
|||
new_env = new_argv + argc + 1; |
|||
s = (char *) (new_env + envc + 1); |
|||
memcpy(s, linux_process_title.str, linux_process_title.len); |
|||
|
|||
for (i = 0; i < argc; i++) |
|||
new_argv[i] = s + (argv[i] - argv[0]); |
|||
new_argv[argc] = NULL; |
|||
|
|||
s += environ[0] - argv[0]; |
|||
|
|||
for (i = 0; i < envc; i++) |
|||
new_env[i] = s + (environ[i] - environ[0]); |
|||
new_env[envc] = NULL; |
|||
|
|||
environ = new_env; |
|||
return new_argv; |
|||
} |
|||
|
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
/* No need to terminate, last char is always '\0'. */ |
|||
if (linux_process_title.len) |
|||
strncpy(linux_process_title.str, title, linux_process_title.len - 1); |
|||
} |
|||
|
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
if (linux_process_title.str) { |
|||
*len = strlen(linux_process_title.str); |
|||
return linux_process_title.str; |
|||
} |
|||
else { |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
} |
|||
|
|||
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
FILE *f = fopen("/proc/self/stat", "r"); |
|||
if (!f) return -1; |
|||
|
|||
int itmp; |
|||
char ctmp; |
|||
size_t page_size = getpagesize(); |
|||
char *cbuf; |
|||
bool foundExeEnd; |
|||
|
|||
/* PID */ |
|||
if (fscanf(f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Exec file */ |
|||
cbuf = getbuf; |
|||
foundExeEnd = false; |
|||
if (fscanf (f, "%c", cbuf++) == 0) goto error; // (
|
|||
while (1) { |
|||
if (fscanf(f, "%c", cbuf) == 0) goto error; |
|||
if (*cbuf == ')') { |
|||
foundExeEnd = true; |
|||
} else if (foundExeEnd && *cbuf == ' ') { |
|||
*cbuf = 0; |
|||
break; |
|||
} |
|||
|
|||
cbuf++; |
|||
} |
|||
/* State */ |
|||
if (fscanf (f, "%c ", &ctmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Parent process */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Process group */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Session id */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* TTY */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* TTY owner process group */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Flags */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Minor faults (no memory page) */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Minor faults, children */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Major faults (memory page faults) */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Major faults, children */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* utime */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* stime */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* utime, children */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* stime, children */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* jiffies remaining in current time slice */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* 'nice' value */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* jiffies until next timeout */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* jiffies until next SIGALRM */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* start time (jiffies since system boot) */ |
|||
if (fscanf (f, "%d ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
|
|||
/* Virtual memory size */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
|
|||
/* Resident set size */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
*rss = (size_t) itmp * page_size; |
|||
|
|||
/* rlim */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Start of text */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* End of text */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
/* Start of stack */ |
|||
if (fscanf (f, "%u ", &itmp) == 0) goto error; /* coverity[secure_coding] */ |
|||
|
|||
fclose (f); |
|||
|
|||
return 0; |
|||
|
|||
error: |
|||
fclose (f); |
|||
return -1; |
|||
} |
|||
|
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
HandleScope scope; |
|||
Local<Object> cpuinfo; |
|||
Local<Object> cputimes; |
|||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), |
|||
multiplier = ((uint64_t)1000L / ticks), cpuspeed; |
|||
int numcpus = 0, i = 0; |
|||
unsigned long long ticks_user, ticks_sys, ticks_idle, ticks_nice, ticks_intr; |
|||
char line[512], speedPath[256], model[512]; |
|||
FILE *fpStat = fopen("/proc/stat", "r"); |
|||
FILE *fpModel = fopen("/proc/cpuinfo", "r"); |
|||
FILE *fpSpeed; |
|||
|
|||
if (fpModel) { |
|||
while (fgets(line, 511, fpModel) != NULL) { |
|||
if (strncmp(line, "model name", 10) == 0) { |
|||
numcpus++; |
|||
if (numcpus == 1) { |
|||
char *p = strchr(line, ':') + 2; |
|||
strcpy(model, p); |
|||
model[strlen(model)-1] = 0; |
|||
} |
|||
} else if (strncmp(line, "cpu MHz", 7) == 0) { |
|||
if (numcpus == 1) { |
|||
sscanf(line, "%*s %*s : %u", &cpuspeed); |
|||
} |
|||
} |
|||
} |
|||
fclose(fpModel); |
|||
} |
|||
|
|||
*cpus = Array::New(numcpus); |
|||
|
|||
if (fpStat) { |
|||
while (fgets(line, 511, fpStat) != NULL) { |
|||
if (strncmp(line, "cpu ", 4) == 0) { |
|||
continue; |
|||
} else if (strncmp(line, "cpu", 3) != 0) { |
|||
break; |
|||
} |
|||
|
|||
sscanf(line, "%*s %llu %llu %llu %llu %*llu %llu", |
|||
&ticks_user, &ticks_nice, &ticks_sys, &ticks_idle, &ticks_intr); |
|||
snprintf(speedPath, sizeof(speedPath), |
|||
"/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_max_freq", i); |
|||
|
|||
fpSpeed = fopen(speedPath, "r"); |
|||
|
|||
if (fpSpeed) { |
|||
if (fgets(line, 511, fpSpeed) != NULL) { |
|||
sscanf(line, "%u", &cpuspeed); |
|||
cpuspeed /= 1000; |
|||
} |
|||
fclose(fpSpeed); |
|||
} |
|||
|
|||
cpuinfo = Object::New(); |
|||
cputimes = Object::New(); |
|||
cputimes->Set(String::New("user"), Number::New(ticks_user * multiplier)); |
|||
cputimes->Set(String::New("nice"), Number::New(ticks_nice * multiplier)); |
|||
cputimes->Set(String::New("sys"), Number::New(ticks_sys * multiplier)); |
|||
cputimes->Set(String::New("idle"), Number::New(ticks_idle * multiplier)); |
|||
cputimes->Set(String::New("irq"), Number::New(ticks_intr * multiplier)); |
|||
|
|||
cpuinfo->Set(String::New("model"), String::New(model)); |
|||
cpuinfo->Set(String::New("speed"), Number::New(cpuspeed)); |
|||
|
|||
cpuinfo->Set(String::New("times"), cputimes); |
|||
(*cpus)->Set(i++, cpuinfo); |
|||
} |
|||
fclose(fpStat); |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
#ifdef CLOCK_MONOTONIC |
|||
struct timespec now; |
|||
if (0 == clock_gettime(CLOCK_MONOTONIC, &now)) { |
|||
double uptime = now.tv_sec; |
|||
uptime += (double)now.tv_nsec / 1000000000.0; |
|||
return uptime; |
|||
} |
|||
return -1; |
|||
#else |
|||
struct sysinfo info; |
|||
if (sysinfo(&info) < 0) { |
|||
return -1; |
|||
} |
|||
return static_cast<double>(info.uptime); |
|||
#endif |
|||
} |
|||
|
|||
|
|||
bool IsInternal(struct ifaddrs* addr) { |
|||
return addr->ifa_flags & IFF_UP && |
|||
addr->ifa_flags & IFF_RUNNING && |
|||
addr->ifa_flags & IFF_LOOPBACK; |
|||
} |
|||
|
|||
|
|||
Handle<Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
struct ::ifaddrs *addrs, *ent; |
|||
struct ::sockaddr_in *in4; |
|||
struct ::sockaddr_in6 *in6; |
|||
char ip[INET6_ADDRSTRLEN]; |
|||
Local<Object> ret, o; |
|||
Local<String> name, ipaddr, family; |
|||
Local<Array> ifarr; |
|||
|
|||
if (getifaddrs(&addrs) != 0) { |
|||
return ThrowException(ErrnoException(errno, "getifaddrs")); |
|||
} |
|||
|
|||
ret = Object::New(); |
|||
|
|||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) { |
|||
bzero(&ip, sizeof (ip)); |
|||
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { |
|||
continue; |
|||
} |
|||
|
|||
if (ent->ifa_addr == NULL) { |
|||
continue; |
|||
} |
|||
|
|||
/*
|
|||
* On Linux getifaddrs returns information related to the raw underlying |
|||
* devices. We're not interested in this information. |
|||
*/ |
|||
if (ent->ifa_addr->sa_family == PF_PACKET) |
|||
continue; |
|||
|
|||
name = String::New(ent->ifa_name); |
|||
if (ret->Has(name)) { |
|||
ifarr = Local<Array>::Cast(ret->Get(name)); |
|||
} else { |
|||
ifarr = Array::New(); |
|||
ret->Set(name, ifarr); |
|||
} |
|||
|
|||
if (ent->ifa_addr->sa_family == AF_INET6) { |
|||
in6 = (struct sockaddr_in6 *)ent->ifa_addr; |
|||
inet_ntop(AF_INET6, &(in6->sin6_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv6"); |
|||
} else if (ent->ifa_addr->sa_family == AF_INET) { |
|||
in4 = (struct sockaddr_in *)ent->ifa_addr; |
|||
inet_ntop(AF_INET, &(in4->sin_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv4"); |
|||
} else { |
|||
(void) strncpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN); |
|||
family = String::New("<unknown>"); |
|||
} |
|||
|
|||
o = Object::New(); |
|||
o->Set(String::New("address"), String::New(ip)); |
|||
o->Set(String::New("family"), family); |
|||
o->Set(String::New("internal"), ent->ifa_flags & IFF_LOOPBACK ? |
|||
True() : False()); |
|||
|
|||
ifarr->Set(ifarr->Length(), o); |
|||
|
|||
} |
|||
|
|||
freeifaddrs(addrs); |
|||
|
|||
return scope.Close(ret); |
|||
} |
|||
|
|||
|
|||
} // namespace node
|
@ -1,52 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
|
|||
namespace node { |
|||
|
|||
|
|||
char** OS::SetupArgs(int argc, char *argv[]) { |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
void OS::SetProcessTitle(char *title) { |
|||
; |
|||
} |
|||
|
|||
|
|||
const char* OS::GetProcessTitle(int *len) { |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
int OS::GetMemory(size_t *rss) { |
|||
// Not implemented
|
|||
*rss = 0; |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
} // namespace node
|
@ -1,178 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
#include <v8.h> |
|||
|
|||
#include <stdlib.h> |
|||
#include <kvm.h> |
|||
#include <sys/param.h> |
|||
#include <sys/sysctl.h> |
|||
#include <sys/user.h> |
|||
#include <sys/dkstat.h> |
|||
#include <uvm/uvm_param.h> |
|||
#include <string.h> |
|||
#include <paths.h> |
|||
#include <fcntl.h> |
|||
#include <unistd.h> |
|||
#include <time.h> |
|||
#include <stdio.h> |
|||
|
|||
#include <node_vars.h> |
|||
#define process_title NODE_VAR(process_title) |
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
process_title = argc ? strdup(argv[0]) : NULL; |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
if (process_title) free(process_title); |
|||
process_title = strdup(title); |
|||
setproctitle(title); |
|||
} |
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
if (process_title) { |
|||
*len = strlen(process_title); |
|||
return process_title; |
|||
} |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
kvm_t *kd = NULL; |
|||
struct kinfo_proc2 *kinfo = NULL; |
|||
pid_t pid; |
|||
int nprocs, max_size = sizeof(struct kinfo_proc2); |
|||
size_t page_size = getpagesize(); |
|||
|
|||
pid = getpid(); |
|||
|
|||
kd = kvm_open(NULL, _PATH_MEM, NULL, O_RDONLY, "kvm_open"); |
|||
if (kd == NULL) goto error; |
|||
|
|||
kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs); |
|||
if (kinfo == NULL) goto error; |
|||
|
|||
*rss = kinfo->p_vm_rssize * page_size; |
|||
|
|||
kvm_close(kd); |
|||
|
|||
return 0; |
|||
|
|||
error: |
|||
if (kd) kvm_close(kd); |
|||
return -1; |
|||
} |
|||
|
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
Local<Object> cpuinfo; |
|||
Local<Object> cputimes; |
|||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), |
|||
multiplier = ((uint64_t)1000L / ticks), cpuspeed; |
|||
uint64_t info[CPUSTATES]; |
|||
char model[512]; |
|||
int numcpus = 1; |
|||
static int which[] = {CTL_HW, HW_MODEL, NULL}; |
|||
size_t size; |
|||
|
|||
size = sizeof(model); |
|||
if (sysctl(which, 2, &model, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
which[1] = HW_NCPU; |
|||
size = sizeof(numcpus); |
|||
if (sysctl(which, 2, &numcpus, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
|
|||
*cpus = Array::New(numcpus); |
|||
|
|||
which[1] = HW_CPUSPEED; |
|||
size = sizeof(cpuspeed); |
|||
if (sysctl(which, 2, &cpuspeed, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
size = sizeof(info); |
|||
which[0] = CTL_KERN; |
|||
which[1] = KERN_CPTIME2; |
|||
for (int i = 0; i < numcpus; i++) { |
|||
which[2] = i; |
|||
size = sizeof(info); |
|||
if (sysctl(which, 3, &info, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
cpuinfo = Object::New(); |
|||
cputimes = Object::New(); |
|||
cputimes->Set(String::New("user"), |
|||
Number::New((uint64_t)(info[CP_USER]) * multiplier)); |
|||
cputimes->Set(String::New("nice"), |
|||
Number::New((uint64_t)(info[CP_NICE]) * multiplier)); |
|||
cputimes->Set(String::New("sys"), |
|||
Number::New((uint64_t)(info[CP_SYS]) * multiplier)); |
|||
cputimes->Set(String::New("idle"), |
|||
Number::New((uint64_t)(info[CP_IDLE]) * multiplier)); |
|||
cputimes->Set(String::New("irq"), |
|||
Number::New((uint64_t)(info[CP_INTR]) * multiplier)); |
|||
|
|||
cpuinfo->Set(String::New("model"), String::New(model)); |
|||
cpuinfo->Set(String::New("speed"), Number::New(cpuspeed)); |
|||
|
|||
cpuinfo->Set(String::New("times"), cputimes); |
|||
(*cpus)->Set(i, cpuinfo); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
time_t now; |
|||
struct timeval info; |
|||
size_t size = sizeof(info); |
|||
static int which[] = {CTL_KERN, KERN_BOOTTIME}; |
|||
|
|||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) { |
|||
return -1; |
|||
} |
|||
now = time(NULL); |
|||
|
|||
return static_cast<double>(now - info.tv_sec); |
|||
} |
|||
|
|||
|
|||
Handle<Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
return scope.Close(Object::New()); |
|||
} |
|||
|
|||
|
|||
} // namespace node
|
@ -1,305 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#include "node.h" |
|||
#include "platform.h" |
|||
|
|||
|
|||
#include <unistd.h> /* getpagesize() */ |
|||
#include <stdlib.h> /* getexecname() */ |
|||
#include <strings.h> /* strncpy() */ |
|||
|
|||
#include <kstat.h> |
|||
#include <errno.h> |
|||
#include <inttypes.h> |
|||
#include <sys/types.h> |
|||
#include <sys/loadavg.h> |
|||
#include <sys/socket.h> |
|||
#include <net/if.h> |
|||
#include <netinet/in.h> |
|||
#include <arpa/inet.h> |
|||
|
|||
#ifdef SUNOS_HAVE_IFADDRS |
|||
# include <ifaddrs.h> |
|||
#endif |
|||
|
|||
|
|||
|
|||
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64) |
|||
#define PROCFS_FILE_OFFSET_BITS_HACK 1 |
|||
#undef _FILE_OFFSET_BITS |
|||
#else |
|||
#define PROCFS_FILE_OFFSET_BITS_HACK 0 |
|||
#endif |
|||
|
|||
#include <procfs.h> |
|||
|
|||
#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1) |
|||
#define _FILE_OFFSET_BITS 64 |
|||
#endif |
|||
|
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
; |
|||
} |
|||
|
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
pid_t pid = getpid(); |
|||
|
|||
char pidpath[1024]; |
|||
sprintf(pidpath, "/proc/%d/psinfo", pid); |
|||
|
|||
psinfo_t psinfo; |
|||
FILE *f = fopen(pidpath, "r"); |
|||
if (!f) return -1; |
|||
|
|||
if (fread(&psinfo, sizeof(psinfo_t), 1, f) != 1) { |
|||
fclose (f); |
|||
return -1; |
|||
} |
|||
|
|||
/* XXX correct? */ |
|||
|
|||
*rss = (size_t) psinfo.pr_rssize * 1024; |
|||
|
|||
fclose (f); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
static Handle<Value> data_named(kstat_named_t *knp) { |
|||
Handle<Value> val; |
|||
|
|||
switch (knp->data_type) { |
|||
case KSTAT_DATA_CHAR: |
|||
val = Number::New(knp->value.c[0]); |
|||
break; |
|||
case KSTAT_DATA_INT32: |
|||
val = Number::New(knp->value.i32); |
|||
break; |
|||
case KSTAT_DATA_UINT32: |
|||
val = Number::New(knp->value.ui32); |
|||
break; |
|||
case KSTAT_DATA_INT64: |
|||
val = Number::New(knp->value.i64); |
|||
break; |
|||
case KSTAT_DATA_UINT64: |
|||
val = Number::New(knp->value.ui64); |
|||
break; |
|||
case KSTAT_DATA_STRING: |
|||
val = String::New(KSTAT_NAMED_STR_PTR(knp)); |
|||
break; |
|||
default: |
|||
val = String::New("unrecognized data type"); |
|||
} |
|||
|
|||
return (val); |
|||
} |
|||
|
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
HandleScope scope; |
|||
Local<Object> cpuinfo; |
|||
Local<Object> cputimes; |
|||
|
|||
int lookup_instance; |
|||
kstat_ctl_t *kc; |
|||
kstat_t *ksp; |
|||
kstat_named_t *knp; |
|||
|
|||
if ((kc = kstat_open()) == NULL) |
|||
return -1; |
|||
|
|||
*cpus = Array::New(); |
|||
|
|||
lookup_instance = 0; |
|||
while (ksp = kstat_lookup(kc, (char *)"cpu_info", lookup_instance, NULL)){ |
|||
cpuinfo = Object::New(); |
|||
|
|||
if (kstat_read(kc, ksp, NULL) == -1) { |
|||
/*
|
|||
* It is deeply annoying, but some kstats can return errors |
|||
* under otherwise routine conditions. (ACPI is one |
|||
* offender; there are surely others.) To prevent these |
|||
* fouled kstats from completely ruining our day, we assign |
|||
* an "error" member to the return value that consists of |
|||
* the strerror(). |
|||
*/ |
|||
cpuinfo->Set(String::New("error"), String::New(strerror(errno))); |
|||
(*cpus)->Set(lookup_instance, cpuinfo); |
|||
} else { |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"clock_MHz"); |
|||
cpuinfo->Set(String::New("speed"), data_named(knp)); |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"brand"); |
|||
cpuinfo->Set(String::New("model"), data_named(knp)); |
|||
(*cpus)->Set(lookup_instance, cpuinfo); |
|||
} |
|||
|
|||
lookup_instance++; |
|||
} |
|||
|
|||
lookup_instance = 0; |
|||
while (ksp = kstat_lookup(kc, (char *)"cpu", lookup_instance, (char *)"sys")){ |
|||
cpuinfo = (*cpus)->Get(lookup_instance)->ToObject(); |
|||
cputimes = Object::New(); |
|||
|
|||
if (kstat_read(kc, ksp, NULL) == -1) { |
|||
cputimes->Set(String::New("error"), String::New(strerror(errno))); |
|||
cpuinfo->Set(String::New("times"), cpuinfo); |
|||
} else { |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"cpu_ticks_kernel"); |
|||
cputimes->Set(String::New("system"), data_named(knp)); |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"cpu_ticks_user"); |
|||
cputimes->Set(String::New("user"), data_named(knp)); |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"cpu_ticks_idle"); |
|||
cputimes->Set(String::New("idle"), data_named(knp)); |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"intr"); |
|||
cputimes->Set(String::New("irq"), data_named(knp)); |
|||
|
|||
cpuinfo->Set(String::New("times"), cputimes); |
|||
} |
|||
|
|||
lookup_instance++; |
|||
} |
|||
|
|||
kstat_close(kc); |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
kstat_ctl_t *kc; |
|||
kstat_t *ksp; |
|||
kstat_named_t *knp; |
|||
|
|||
long hz = sysconf(_SC_CLK_TCK); |
|||
double clk_intr; |
|||
|
|||
if ((kc = kstat_open()) == NULL) |
|||
return -1; |
|||
|
|||
ksp = kstat_lookup(kc, (char *)"unix", 0, (char *)"system_misc"); |
|||
|
|||
if (kstat_read(kc, ksp, NULL) == -1) { |
|||
clk_intr = -1; |
|||
} else { |
|||
knp = (kstat_named_t *) kstat_data_lookup(ksp, (char *)"clk_intr"); |
|||
clk_intr = knp->value.ul / hz; |
|||
} |
|||
|
|||
kstat_close(kc); |
|||
|
|||
return clk_intr; |
|||
} |
|||
|
|||
|
|||
Handle<Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
|
|||
#ifndef SUNOS_HAVE_IFADDRS |
|||
return ThrowException(Exception::Error(String::New( |
|||
"This version of sunos doesn't support getifaddrs"))); |
|||
#else |
|||
struct ::ifaddrs *addrs, *ent; |
|||
struct ::sockaddr_in *in4; |
|||
struct ::sockaddr_in6 *in6; |
|||
char ip[INET6_ADDRSTRLEN]; |
|||
Local<Object> ret, o; |
|||
Local<String> name, ipaddr, family; |
|||
Local<Array> ifarr; |
|||
|
|||
if (getifaddrs(&addrs) != 0) { |
|||
return ThrowException(ErrnoException(errno, "getifaddrs")); |
|||
} |
|||
|
|||
ret = Object::New(); |
|||
|
|||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) { |
|||
bzero(&ip, sizeof (ip)); |
|||
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) { |
|||
continue; |
|||
} |
|||
|
|||
if (ent->ifa_addr == NULL) { |
|||
continue; |
|||
} |
|||
|
|||
name = String::New(ent->ifa_name); |
|||
if (ret->Has(name)) { |
|||
ifarr = Local<Array>::Cast(ret->Get(name)); |
|||
} else { |
|||
ifarr = Array::New(); |
|||
ret->Set(name, ifarr); |
|||
} |
|||
|
|||
if (ent->ifa_addr->sa_family == AF_INET6) { |
|||
in6 = (struct sockaddr_in6 *)ent->ifa_addr; |
|||
inet_ntop(AF_INET6, &(in6->sin6_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv6"); |
|||
} else if (ent->ifa_addr->sa_family == AF_INET) { |
|||
in4 = (struct sockaddr_in *)ent->ifa_addr; |
|||
inet_ntop(AF_INET, &(in4->sin_addr), ip, INET6_ADDRSTRLEN); |
|||
family = String::New("IPv4"); |
|||
} else { |
|||
(void) strlcpy(ip, "<unknown sa family>", INET6_ADDRSTRLEN); |
|||
family = String::New("<unknown>"); |
|||
} |
|||
|
|||
o = Object::New(); |
|||
o->Set(String::New("address"), String::New(ip)); |
|||
o->Set(String::New("family"), family); |
|||
o->Set(String::New("internal"), ent->ifa_flags & IFF_PRIVATE || ent->ifa_flags & |
|||
IFF_LOOPBACK ? True() : False()); |
|||
|
|||
ifarr->Set(ifarr->Length(), o); |
|||
|
|||
} |
|||
|
|||
freeifaddrs(addrs); |
|||
|
|||
return scope.Close(ret); |
|||
|
|||
#endif // SUNOS_HAVE_IFADDRS
|
|||
} |
|||
|
|||
|
|||
} // namespace node
|
|||
|
@ -1,292 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
|
|||
#include <node.h> |
|||
#include "platform.h" |
|||
|
|||
#include <v8.h> |
|||
|
|||
#include <errno.h> |
|||
#include <stdlib.h> |
|||
#if defined(__MINGW32__) |
|||
#include <sys/param.h> // for MAXPATHLEN |
|||
#include <unistd.h> // getpagesize |
|||
#endif |
|||
|
|||
#include <platform_win32.h> |
|||
#include <psapi.h> |
|||
|
|||
#include <node_vars.h> |
|||
#define process_title NODE_VAR(process_title) |
|||
|
|||
namespace node { |
|||
|
|||
using namespace v8; |
|||
|
|||
double Platform::prog_start_time = Platform::GetUptime(); |
|||
|
|||
|
|||
// Does the about the same as strerror(),
|
|||
// but supports all windows errror messages
|
|||
const char *winapi_strerror(const int errorno) { |
|||
char *errmsg = NULL; |
|||
|
|||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | |
|||
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, |
|||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL); |
|||
|
|||
if (errmsg) { |
|||
// Remove trailing newlines
|
|||
for (int i = strlen(errmsg) - 1; |
|||
i >= 0 && (errmsg[i] == '\n' || errmsg[i] == '\r'); i--) { |
|||
errmsg[i] = '\0'; |
|||
} |
|||
|
|||
return errmsg; |
|||
} else { |
|||
// FormatMessage failed
|
|||
return "Unknown error"; |
|||
} |
|||
} |
|||
|
|||
|
|||
// Does the about the same as perror(), but for windows api functions
|
|||
void winapi_perror(const char* prefix = NULL) { |
|||
DWORD errorno = GetLastError(); |
|||
const char *errmsg = NULL; |
|||
|
|||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | |
|||
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, |
|||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&errmsg, 0, NULL); |
|||
|
|||
if (!errmsg) { |
|||
errmsg = "Unknown error\n"; |
|||
} |
|||
|
|||
// FormatMessage messages include a newline character
|
|||
|
|||
if (prefix) { |
|||
fprintf(stderr, "%s: %s", prefix, errmsg); |
|||
} else { |
|||
fputs(errmsg, stderr); |
|||
} |
|||
} |
|||
|
|||
|
|||
char** Platform::SetupArgs(int argc, char *argv[]) { |
|||
return argv; |
|||
} |
|||
|
|||
|
|||
// Max title length; the only thing MSDN tells us about the maximum length
|
|||
// of the console title is that it is smaller than 64K. However in practice
|
|||
// it is much smaller, and there is no way to figure out what the exact length
|
|||
// of the title is or can be, at least not on XP. To make it even more
|
|||
// annoying, GetConsoleTitle failes when the buffer to be read into is bigger
|
|||
// than the actual maximum length. So we make a conservative guess here;
|
|||
// just don't put the novel you're writing in the title, unless the plot
|
|||
// survives truncation.
|
|||
#define MAX_TITLE_LENGTH 8192 |
|||
|
|||
void Platform::SetProcessTitle(char *title) { |
|||
// We need to convert _title_ to UTF-16 first, because that's what windows uses internally.
|
|||
// It would be more efficient to use the UTF-16 value that we can obtain from v8,
|
|||
// but it's not accessible from here.
|
|||
|
|||
int length; |
|||
WCHAR *title_w; |
|||
|
|||
// Find out how big the buffer for the wide-char title must be
|
|||
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); |
|||
if (!length) { |
|||
winapi_perror("MultiByteToWideChar"); |
|||
return; |
|||
} |
|||
|
|||
// Convert to wide-char string
|
|||
title_w = new WCHAR[length]; |
|||
length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); |
|||
if (!length) { |
|||
winapi_perror("MultiByteToWideChar"); |
|||
delete title_w; |
|||
return; |
|||
}; |
|||
|
|||
// If the title must be truncated insert a \0 terminator there
|
|||
if (length > MAX_TITLE_LENGTH) { |
|||
title_w[MAX_TITLE_LENGTH - 1] = *L"\0"; |
|||
} |
|||
|
|||
if (!SetConsoleTitleW(title_w)) { |
|||
winapi_perror("SetConsoleTitleW"); |
|||
} |
|||
|
|||
free(process_title); |
|||
process_title = strdup(title); |
|||
|
|||
delete title_w; |
|||
} |
|||
|
|||
|
|||
static inline char* _getProcessTitle() { |
|||
WCHAR title_w[MAX_TITLE_LENGTH]; |
|||
char *title; |
|||
int result, length; |
|||
|
|||
result = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR)); |
|||
|
|||
if (result == 0) { |
|||
winapi_perror("GetConsoleTitleW"); |
|||
return NULL; |
|||
} |
|||
|
|||
// Find out what the size of the buffer is that we need
|
|||
length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL); |
|||
if (!length) { |
|||
winapi_perror("WideCharToMultiByte"); |
|||
return NULL; |
|||
} |
|||
|
|||
title = (char *) malloc(length); |
|||
if (!title) { |
|||
perror("malloc"); |
|||
return NULL; |
|||
} |
|||
|
|||
// Do utf16 -> utf8 conversion here
|
|||
if (!WideCharToMultiByte(CP_UTF8, 0, title_w, -1, title, length, NULL, NULL)) { |
|||
winapi_perror("WideCharToMultiByte"); |
|||
free(title); |
|||
return NULL; |
|||
} |
|||
|
|||
return title; |
|||
} |
|||
|
|||
|
|||
const char* Platform::GetProcessTitle(int *len) { |
|||
// If the process_title was never read before nor explicitly set,
|
|||
// we must query it with getConsoleTitleW
|
|||
if (!process_title) { |
|||
process_title = _getProcessTitle(); |
|||
} |
|||
|
|||
if (process_title) { |
|||
*len = strlen(process_title); |
|||
return process_title; |
|||
} else { |
|||
*len = 0; |
|||
return NULL; |
|||
} |
|||
} |
|||
|
|||
|
|||
int Platform::GetMemory(size_t *rss) { |
|||
|
|||
HANDLE current_process = GetCurrentProcess(); |
|||
PROCESS_MEMORY_COUNTERS pmc; |
|||
|
|||
if ( !GetProcessMemoryInfo( current_process, &pmc, sizeof(pmc)) ) |
|||
{ |
|||
winapi_perror("GetProcessMemoryInfo"); |
|||
} |
|||
|
|||
*rss = pmc.WorkingSetSize; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
int Platform::GetCPUInfo(Local<Array> *cpus) { |
|||
|
|||
HandleScope scope; |
|||
*cpus = Array::New(); |
|||
|
|||
for (int i = 0; i < 32; i++) { |
|||
|
|||
char key[128] = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; |
|||
char processor_number[32]; |
|||
itoa(i, processor_number, 10); |
|||
strncat(key, processor_number, 2); |
|||
|
|||
HKEY processor_key = NULL; |
|||
|
|||
DWORD cpu_speed = 0; |
|||
DWORD cpu_speed_length = sizeof(cpu_speed); |
|||
|
|||
char cpu_brand[256]; |
|||
DWORD cpu_brand_length = sizeof(cpu_brand); |
|||
|
|||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE, |
|||
&processor_key) != ERROR_SUCCESS) { |
|||
if (i == 0) { |
|||
winapi_perror("RegOpenKeyEx"); |
|||
return -1; |
|||
} |
|||
|
|||
continue; |
|||
} |
|||
|
|||
if (RegQueryValueEx(processor_key, "~MHz", NULL, NULL, |
|||
(LPBYTE)&cpu_speed, &cpu_speed_length) |
|||
!= ERROR_SUCCESS) { |
|||
winapi_perror("RegQueryValueEx"); |
|||
return -1; |
|||
} |
|||
|
|||
if (RegQueryValueEx(processor_key, "ProcessorNameString", NULL, NULL, |
|||
(LPBYTE)&cpu_brand, &cpu_brand_length) |
|||
!= ERROR_SUCCESS) { |
|||
winapi_perror("RegQueryValueEx"); |
|||
return -1; |
|||
} |
|||
|
|||
RegCloseKey(processor_key); |
|||
|
|||
Local<Object> times_info = Object::New(); // FIXME - find times on windows
|
|||
times_info->Set(String::New("user"), Integer::New(0)); |
|||
times_info->Set(String::New("nice"), Integer::New(0)); |
|||
times_info->Set(String::New("sys"), Integer::New(0)); |
|||
times_info->Set(String::New("idle"), Integer::New(0)); |
|||
times_info->Set(String::New("irq"), Integer::New(0)); |
|||
|
|||
Local<Object> cpu_info = Object::New(); |
|||
cpu_info->Set(String::New("model"), String::New(cpu_brand)); |
|||
cpu_info->Set(String::New("speed"), Integer::New(cpu_speed)); |
|||
cpu_info->Set(String::New("times"), times_info); |
|||
(*cpus)->Set(i,cpu_info); |
|||
} |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
|
|||
double Platform::GetUptimeImpl() { |
|||
return (double)GetTickCount()/1000.0; |
|||
} |
|||
|
|||
Handle<Value> Platform::GetInterfaceAddresses() { |
|||
HandleScope scope; |
|||
return scope.Close(Object::New()); |
|||
} |
|||
|
|||
|
|||
} // namespace node
|
@ -1,79 +0,0 @@ |
|||
// Copyright Joyent, Inc. and other Node contributors.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
// copy of this software and associated documentation files (the
|
|||
// "Software"), to deal in the Software without restriction, including
|
|||
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
// persons to whom the Software is furnished to do so, subject to the
|
|||
// following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included
|
|||
// in all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|||
#ifndef NODE_PLATFORM_WIN32_H_ |
|||
#define NODE_PLATFORM_WIN32_H_ |
|||
|
|||
// Require at least Windows XP SP1
|
|||
// (GetProcessId requires it)
|
|||
#ifndef _WIN32_WINNT |
|||
# define _WIN32_WINNT 0x0501 |
|||
#endif |
|||
|
|||
#ifndef WIN32_LEAN_AND_MEAN |
|||
# define WIN32_LEAN_AND_MEAN // implies NOCRYPT and NOGDI.
|
|||
#endif |
|||
|
|||
#ifndef NOMINMAX |
|||
# define NOMINMAX |
|||
#endif |
|||
|
|||
#ifndef NOKERNEL |
|||
# define NOKERNEL |
|||
#endif |
|||
|
|||
#ifndef NOUSER |
|||
# define NOUSER |
|||
#endif |
|||
|
|||
#ifndef NOSERVICE |
|||
# define NOSERVICE |
|||
#endif |
|||
|
|||
#ifndef NOSOUND |
|||
# define NOSOUND |
|||
#endif |
|||
|
|||
#ifndef NOMCX |
|||
# define NOMCX |
|||
#endif |
|||
|
|||
#include <windows.h> |
|||
#include <winsock2.h> |
|||
|
|||
#if defined(_MSC_VER) |
|||
#define STDIN_FILENO 0 |
|||
#define STDOUT_FILENO 1 |
|||
#define STDERR_FILENO 2 |
|||
#endif |
|||
|
|||
namespace node { |
|||
|
|||
#define NO_IMPL_MSG(...) \ |
|||
fprintf(stderr, "Not implemented: %s\n", #__VA_ARGS__); |
|||
|
|||
const char *winapi_strerror(const int errorno); |
|||
void winapi_perror(const char* prefix); |
|||
|
|||
} |
|||
|
|||
#endif // NODE_PLATFORM_WIN32_H_
|
|||
|
Loading…
Reference in new issue