904
static Persistent<FunctionTemplate> stats_constructor_template;
906
Local<Object> BuildStatsObject(struct stat * s) {
909
if (dev_symbol.IsEmpty()) {
910
dev_symbol = NODE_PSYMBOL("dev");
911
ino_symbol = NODE_PSYMBOL("ino");
912
mode_symbol = NODE_PSYMBOL("mode");
913
nlink_symbol = NODE_PSYMBOL("nlink");
914
uid_symbol = NODE_PSYMBOL("uid");
915
gid_symbol = NODE_PSYMBOL("gid");
916
rdev_symbol = NODE_PSYMBOL("rdev");
917
size_symbol = NODE_PSYMBOL("size");
918
blksize_symbol = NODE_PSYMBOL("blksize");
919
blocks_symbol = NODE_PSYMBOL("blocks");
920
atime_symbol = NODE_PSYMBOL("atime");
921
mtime_symbol = NODE_PSYMBOL("mtime");
922
ctime_symbol = NODE_PSYMBOL("ctime");
925
Local<Object> stats =
926
stats_constructor_template->GetFunction()->NewInstance();
928
/* ID of device containing file */
929
stats->Set(dev_symbol, Integer::New(s->st_dev));
932
stats->Set(ino_symbol, Integer::New(s->st_ino));
935
stats->Set(mode_symbol, Integer::New(s->st_mode));
937
/* number of hard links */
938
stats->Set(nlink_symbol, Integer::New(s->st_nlink));
940
/* user ID of owner */
941
stats->Set(uid_symbol, Integer::New(s->st_uid));
943
/* group ID of owner */
944
stats->Set(gid_symbol, Integer::New(s->st_gid));
946
/* device ID (if special file) */
947
stats->Set(rdev_symbol, Integer::New(s->st_rdev));
949
/* total size, in bytes */
950
stats->Set(size_symbol, Number::New(s->st_size));
952
/* blocksize for filesystem I/O */
953
stats->Set(blksize_symbol, Integer::New(s->st_blksize));
955
/* number of blocks allocated */
956
stats->Set(blocks_symbol, Integer::New(s->st_blocks));
958
/* time of last access */
959
stats->Set(atime_symbol, NODE_UNIXTIME_V8(s->st_atime));
961
/* time of last modification */
962
stats->Set(mtime_symbol, NODE_UNIXTIME_V8(s->st_mtime));
964
/* time of last status change */
965
stats->Set(ctime_symbol, NODE_UNIXTIME_V8(s->st_ctime));
967
return scope.Close(stats);
971
898
// Extracts a C str from a V8 Utf8Value.
972
899
const char* ToCString(const v8::String::Utf8Value& value) {
973
900
return *value ? *value : "<str conversion failed>";
1224
1155
v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
1225
1156
HandleScope scope;
1228
1157
exit(args[0]->IntegerValue());
1229
1158
return Undefined();
1233
#define HAVE_GETMEM 1
1234
#include <unistd.h> /* getpagesize() */
1236
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
1237
#define PROCFS_FILE_OFFSET_BITS_HACK 1
1238
#undef _FILE_OFFSET_BITS
1240
#define PROCFS_FILE_OFFSET_BITS_HACK 0
1245
#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1)
1246
#define _FILE_OFFSET_BITS 64
1249
int getmem(size_t *rss, size_t *vsize) {
1250
pid_t pid = getpid();
1252
size_t page_size = getpagesize();
1254
sprintf(pidpath, "/proc/%d/psinfo", pid);
1257
FILE *f = fopen(pidpath, "r");
1260
if (fread(&psinfo, sizeof(psinfo_t), 1, f) != 1) {
1267
*vsize = (size_t) psinfo.pr_size * page_size;
1268
*rss = (size_t) psinfo.pr_rssize * 1024;
1278
#define HAVE_GETMEM 1
1280
#include <sys/param.h>
1281
#include <sys/sysctl.h>
1282
#include <sys/user.h>
1287
int getmem(size_t *rss, size_t *vsize) {
1289
struct kinfo_proc *kinfo = NULL;
1292
size_t page_size = getpagesize();
1296
kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open");
1297
if (kd == NULL) goto error;
1299
kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs);
1300
if (kinfo == NULL) goto error;
1302
*rss = kinfo->ki_rssize * page_size;
1303
*vsize = kinfo->ki_size;
1310
if (kd) kvm_close(kd);
1313
#endif // __FreeBSD__
1317
#define HAVE_GETMEM 1
1318
/* Researched by Tim Becker and Michael Knight
1319
* http://blog.kuriositaet.de/?p=257
1322
#include <mach/task.h>
1323
#include <mach/mach_init.h>
1325
int getmem(size_t *rss, size_t *vsize) {
1326
struct task_basic_info t_info;
1327
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
1329
int r = task_info(mach_task_self(),
1331
(task_info_t)&t_info,
1334
if (r != KERN_SUCCESS) return -1;
1336
*rss = t_info.resident_size;
1337
*vsize = t_info.virtual_size;
1344
# define HAVE_GETMEM 1
1345
# include <sys/param.h> /* for MAXPATHLEN */
1347
int getmem(size_t *rss, size_t *vsize) {
1348
FILE *f = fopen("/proc/self/stat", "r");
1353
char buffer[MAXPATHLEN];
1354
size_t page_size = getpagesize();
1357
if (fscanf(f, "%d ", &itmp) == 0) goto error;
1359
if (fscanf (f, "%s ", &buffer[0]) == 0) goto error;
1361
if (fscanf (f, "%c ", &ctmp) == 0) goto error;
1362
/* Parent process */
1363
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1365
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1367
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1369
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1370
/* TTY owner process group */
1371
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1373
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1374
/* Minor faults (no memory page) */
1375
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1376
/* Minor faults, children */
1377
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1378
/* Major faults (memory page faults) */
1379
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1380
/* Major faults, children */
1381
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1383
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1385
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1386
/* utime, children */
1387
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1388
/* stime, children */
1389
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1390
/* jiffies remaining in current time slice */
1391
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1393
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1394
/* jiffies until next timeout */
1395
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1396
/* jiffies until next SIGALRM */
1397
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1398
/* start time (jiffies since system boot) */
1399
if (fscanf (f, "%d ", &itmp) == 0) goto error;
1401
/* Virtual memory size */
1402
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1403
*vsize = (size_t) itmp;
1405
/* Resident set size */
1406
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1407
*rss = (size_t) itmp * page_size;
1410
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1412
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1414
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1415
/* Start of stack */
1416
if (fscanf (f, "%u ", &itmp) == 0) goto error;
1429
1162
static void CheckStatus(EV_P_ ev_timer *watcher, int revents) {
1430
1163
assert(watcher == &gc_timer);
1431
assert(revents == EV_TIMER);
1164
assert(revents == EV_TIMEOUT);
1434
1166
// check memory
1435
1167
size_t rss, vsize;
1436
if (!ev_is_active(&gc_idle) && getmem(&rss, &vsize) == 0) {
1168
if (!ev_is_active(&gc_idle) && OS::GetMemory(&rss, &vsize) == 0) {
1437
1169
if (rss > 1024*1024*128) {
1438
1170
// larger than 128 megs, just start the idle watcher
1439
1171
ev_idle_start(EV_A_ &gc_idle);
1443
#endif // HAVE_GETMEM
1445
1176
double d = ev_now(EV_DEFAULT_UC) - TICK_TIME(3);
1551
1278
return ThrowException(exception);
1281
String::Utf8Value symbol(args[0]->ToString());
1282
char *symstr = NULL;
1284
char *sym = *symbol;
1285
char *p = strrchr(sym, '/');
1290
p = strrchr(sym, '.');
1295
size_t slen = strlen(sym);
1296
symstr = static_cast<char*>(calloc(1, slen + sizeof("_module") + 1));
1297
memcpy(symstr, sym, slen);
1298
memcpy(symstr+slen, "_module", sizeof("_module") + 1);
1554
1301
// Get the init() function from the dynamically shared object.
1555
void *init_handle = dlsym(handle, "init");
1302
node_module_struct *mod = static_cast<node_module_struct *>(dlsym(handle, symstr));
1556
1304
// Error out if not found.
1557
if (init_handle == NULL) {
1306
/* Start Compatibility hack: Remove once everyone is using NODE_MODULE macro */
1307
node_module_struct compat_mod;
1309
mod->version = NODE_MODULE_VERSION;
1311
void *init_handle = dlsym(handle, "init");
1312
if (init_handle == NULL) {
1314
Local<Value> exception =
1315
Exception::Error(String::New("No module symbol found in module."));
1316
return ThrowException(exception);
1318
mod->register_func = (extInit)(init_handle);
1319
/* End Compatibility hack */
1322
if (mod->version != NODE_MODULE_VERSION) {
1558
1323
Local<Value> exception =
1559
Exception::Error(String::New("No 'init' symbol found in module."));
1324
Exception::Error(String::New("Module version mismatch, refusing to load."));
1560
1325
return ThrowException(exception);
1562
extInit init = (extInit)(init_handle); // Cast
1564
1328
// Execute the C++ module
1329
mod->register_func(target);
1331
// Tell coverity that 'handle' should not be freed when we return.
1332
// coverity[leaked_storage]
1567
1333
return Undefined();
1734
1465
Local<Object> exports;
1736
// TODO DRY THIS UP!
1738
if (!strcmp(*module_v, "stdio")) {
1739
if (binding_cache->Has(module)) {
1740
exports = binding_cache->Get(module)->ToObject();
1742
exports = Object::New();
1743
Stdio::Initialize(exports);
1744
binding_cache->Set(module, exports);
1747
} else if (!strcmp(*module_v, "cares")) {
1748
if (binding_cache->Has(module)) {
1749
exports = binding_cache->Get(module)->ToObject();
1751
exports = Object::New();
1752
Cares::Initialize(exports);
1753
binding_cache->Set(module, exports);
1756
} else if (!strcmp(*module_v, "fs")) {
1757
if (binding_cache->Has(module)) {
1758
exports = binding_cache->Get(module)->ToObject();
1760
exports = Object::New();
1762
// Initialize the stats object
1763
Local<FunctionTemplate> stat_templ = FunctionTemplate::New();
1764
stats_constructor_template = Persistent<FunctionTemplate>::New(stat_templ);
1765
exports->Set(String::NewSymbol("Stats"),
1766
stats_constructor_template->GetFunction());
1767
StatWatcher::Initialize(exports);
1768
File::Initialize(exports);
1769
binding_cache->Set(module, exports);
1772
} else if (!strcmp(*module_v, "signal_watcher")) {
1773
if (binding_cache->Has(module)) {
1774
exports = binding_cache->Get(module)->ToObject();
1776
exports = Object::New();
1777
SignalWatcher::Initialize(exports);
1778
binding_cache->Set(module, exports);
1781
} else if (!strcmp(*module_v, "net")) {
1782
if (binding_cache->Has(module)) {
1783
exports = binding_cache->Get(module)->ToObject();
1785
exports = Object::New();
1787
binding_cache->Set(module, exports);
1790
} else if (!strcmp(*module_v, "http_parser")) {
1791
if (binding_cache->Has(module)) {
1792
exports = binding_cache->Get(module)->ToObject();
1794
exports = Object::New();
1795
InitHttpParser(exports);
1796
binding_cache->Set(module, exports);
1799
} else if (!strcmp(*module_v, "child_process")) {
1800
if (binding_cache->Has(module)) {
1801
exports = binding_cache->Get(module)->ToObject();
1803
exports = Object::New();
1804
ChildProcess::Initialize(exports);
1805
binding_cache->Set(module, exports);
1808
} else if (!strcmp(*module_v, "buffer")) {
1809
if (binding_cache->Has(module)) {
1810
exports = binding_cache->Get(module)->ToObject();
1812
exports = Object::New();
1813
Buffer::Initialize(exports);
1814
binding_cache->Set(module, exports);
1817
} else if (!strcmp(*module_v, "crypto")) {
1818
if (binding_cache->Has(module)) {
1819
exports = binding_cache->Get(module)->ToObject();
1821
exports = Object::New();
1822
InitCrypto(exports);
1823
binding_cache->Set(module, exports);
1826
} else if (!strcmp(*module_v, "evals")) {
1827
if (binding_cache->Has(module)) {
1828
exports = binding_cache->Get(module)->ToObject();
1830
exports = Object::New();
1831
node::Script::Initialize(exports);
1832
binding_cache->Set(module, exports);
1467
if (binding_cache->Has(module)) {
1468
exports = binding_cache->Get(module)->ToObject();
1470
else if ((modp = get_builtin_module(*module_v)) != NULL) {
1471
exports = Object::New();
1472
modp->register_func(exports);
1473
binding_cache->Set(module, exports);
1835
1474
} else if (!strcmp(*module_v, "natives")) {
1836
if (binding_cache->Has(module)) {
1837
exports = binding_cache->Get(module)->ToObject();
1839
exports = Object::New();
1840
// Explicitly define native sources.
1841
// TODO DRY/automate this?
1842
exports->Set(String::New("assert"), String::New(native_assert));
1843
exports->Set(String::New("buffer"), String::New(native_buffer));
1844
exports->Set(String::New("child_process"),String::New(native_child_process));
1845
exports->Set(String::New("dns"), String::New(native_dns));
1846
exports->Set(String::New("events"), String::New(native_events));
1847
exports->Set(String::New("file"), String::New(native_file));
1848
exports->Set(String::New("freelist"), String::New(native_freelist));
1849
exports->Set(String::New("fs"), String::New(native_fs));
1850
exports->Set(String::New("http"), String::New(native_http));
1851
exports->Set(String::New("crypto"), String::New(native_crypto));
1852
exports->Set(String::New("ini"), String::New(native_ini));
1853
exports->Set(String::New("mjsunit"), String::New(native_mjsunit));
1854
exports->Set(String::New("net"), String::New(native_net));
1855
exports->Set(String::New("posix"), String::New(native_posix));
1856
exports->Set(String::New("querystring"), String::New(native_querystring));
1857
exports->Set(String::New("repl"), String::New(native_repl));
1858
exports->Set(String::New("sys"), String::New(native_sys));
1859
exports->Set(String::New("tcp"), String::New(native_tcp));
1860
exports->Set(String::New("uri"), String::New(native_uri));
1861
exports->Set(String::New("url"), String::New(native_url));
1862
exports->Set(String::New("utils"), String::New(native_utils));
1863
exports->Set(String::New("path"), String::New(native_path));
1864
exports->Set(String::New("module"), String::New(native_module));
1865
exports->Set(String::New("utf8decoder"), String::New(native_utf8decoder));
1866
binding_cache->Set(module, exports);
1475
exports = Object::New();
1476
// Explicitly define native sources.
1477
// TODO DRY/automate this?
1478
exports->Set(String::New("assert"), String::New(native_assert));
1479
exports->Set(String::New("buffer"), String::New(native_buffer));
1480
exports->Set(String::New("child_process"),String::New(native_child_process));
1481
exports->Set(String::New("dgram"), String::New(native_dgram));
1482
exports->Set(String::New("dns"), String::New(native_dns));
1483
exports->Set(String::New("events"), String::New(native_events));
1484
exports->Set(String::New("file"), String::New(native_file));
1485
exports->Set(String::New("freelist"), String::New(native_freelist));
1486
exports->Set(String::New("fs"), String::New(native_fs));
1487
exports->Set(String::New("http"), String::New(native_http));
1488
exports->Set(String::New("crypto"), String::New(native_crypto));
1489
exports->Set(String::New("net"), String::New(native_net));
1490
exports->Set(String::New("posix"), String::New(native_posix));
1491
exports->Set(String::New("querystring"), String::New(native_querystring));
1492
exports->Set(String::New("repl"), String::New(native_repl));
1493
exports->Set(String::New("readline"), String::New(native_readline));
1494
exports->Set(String::New("sys"), String::New(native_sys));
1495
exports->Set(String::New("tcp"), String::New(native_tcp));
1496
exports->Set(String::New("url"), String::New(native_url));
1497
exports->Set(String::New("utils"), String::New(native_utils));
1498
exports->Set(String::New("path"), String::New(native_path));
1499
exports->Set(String::New("string_decoder"), String::New(native_string_decoder));
1500
binding_cache->Set(module, exports);
1870
1502
return ThrowException(Exception::Error(String::New("No such module")));
1883
1533
process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());
1536
process->SetAccessor(String::New("title"),
1538
ProcessTitleSetter);
1885
1541
// Add a reference to the global object
1886
Local<Object> global = Context::GetCurrent()->Global();
1542
Local<Object> global = v8::Context::GetCurrent()->Global();
1887
1543
process->Set(String::NewSymbol("global"), global);
1889
1545
// process.version
1890
1546
process->Set(String::NewSymbol("version"), String::New(NODE_VERSION));
1891
1548
// process.installPrefix
1892
1549
process->Set(String::NewSymbol("installPrefix"), String::New(NODE_PREFIX));
1551
Local<Object> versions = Object::New();
1553
process->Set(String::NewSymbol("versions"), versions);
1554
// +1 to get rid of the leading 'v'
1555
versions->Set(String::NewSymbol("node"), String::New(NODE_VERSION+1));
1556
versions->Set(String::NewSymbol("v8"), String::New(V8::GetVersion()));
1557
versions->Set(String::NewSymbol("ares"), String::New(ARES_VERSION_STR));
1558
snprintf(buf, 20, "%d.%d", ev_version_major(), ev_version_minor());
1559
versions->Set(String::NewSymbol("ev"), String::New(buf));
1894
1563
// process.platform
1895
#define xstr(s) str(s)
1897
process->Set(String::NewSymbol("platform"), String::New(xstr(PLATFORM)));
1564
process->Set(String::NewSymbol("platform"), String::New(PLATFORM));
1899
1566
// process.argv
1901
1568
Local<Array> arguments = Array::New(argc - option_end_index + 1);
1902
1569
arguments->Set(Integer::New(0), String::New(argv[0]));
1903
for (j = 1, i = option_end_index + 1; i < argc; j++, i++) {
1570
for (j = 1, i = option_end_index; i < argc; j++, i++) {
1904
1571
Local<String> arg = String::New(argv[i]);
1905
1572
arguments->Set(Integer::New(j), arg);
2070
1750
} else if (strcmp(arg, "--v8-options") == 0) {
2071
1751
argv[i] = const_cast<char*>("--help");
2072
option_end_index = i+1;
2073
1752
} else if (argv[i][0] != '-') {
2074
option_end_index = i-1;
1757
option_end_index = i;
1761
static void AtExit() {
1762
node::Stdio::Flush();
1763
node::Stdio::DisableRawMode(STDIN_FILENO);
2080
1767
} // namespace node
2083
1770
int main(int argc, char *argv[]) {
1771
// Hack aroung with the argv pointer. Used for process.title = "blah".
1772
argv = node::OS::SetupArgs(argc, argv);
2084
1774
// Parse a few arguments which are specific to Node.
2085
1775
node::ParseArgs(&argc, argv);
2086
1776
// Parse the rest of the args (up to the 'option_end_index' (where '--' was
2087
1777
// in the command line))
2088
V8::SetFlagsFromCommandLine(&node::option_end_index, argv, false);
1778
int v8argc = node::option_end_index;
1779
char **v8argv = argv;
2090
// Error out if we don't have a script argument.
2092
fprintf(stderr, "No script was specified.\n");
1781
if (node::debug_wait_connect) {
1782
// v8argv is a copy of argv up to the script file argument +2 if --debug-brk
1783
// to expose the v8 debugger js object so that node.js can set
1784
// a breakpoint on the first line of the startup script
1786
v8argv = new char*[v8argc];
1787
memcpy(v8argv, argv, sizeof(argv) * node::option_end_index);
1788
v8argv[node::option_end_index] = const_cast<char*>("--expose_debug_as");
1789
v8argv[node::option_end_index + 1] = const_cast<char*>("v8debug");
1791
V8::SetFlagsFromCommandLine(&v8argc, v8argv, false);
2098
1793
// Ignore SIGPIPE
2099
1794
struct sigaction sa;