diff --git a/deps/uv/gyp_uv b/deps/uv/gyp_uv index 00da3aedd1..d861cbc786 100755 --- a/deps/uv/gyp_uv +++ b/deps/uv/gyp_uv @@ -58,9 +58,11 @@ if __name__ == '__main__': # There's a bug with windows which doesn't allow this feature. if sys.platform != 'win32': - args.extend(['--generator-output', output_dir]) - args.extend(['-Goutput_dir=' + output_dir]) - args.extend('-f make'.split()) + if '-f' not in args: + args.extend('-f make'.split()) + if 'ninja' not in args: + args.extend(['-Goutput_dir=' + output_dir]) + args.extend(['--generator-output', output_dir]) (major, minor), is_clang = compiler_version() args.append('-Dgcc_version=%d' % (10 * major + minor)) args.append('-Dclang=%d' % int(is_clang)) diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index b2add994a0..e5ef3a011b 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -100,6 +100,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case ENOSPC: return UV_ENOSPC; case EROFS: return UV_EROFS; case ENOMEM: return UV_ENOMEM; + case EDQUOT: return UV_ENOSPC; default: return UV_UNKNOWN; } UNREACHABLE(); diff --git a/deps/uv/src/unix/linux/linux-core.c b/deps/uv/src/unix/linux/linux-core.c index c77c81cc92..bf6efd85b6 100644 --- a/deps/uv/src/unix/linux/linux-core.c +++ b/deps/uv/src/unix/linux/linux-core.c @@ -63,6 +63,11 @@ static struct { size_t len; } process_title; +static void read_models(unsigned int numcpus, uv_cpu_info_t* ci); +static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci); +static void read_times(unsigned int numcpus, uv_cpu_info_t* ci); +static unsigned long read_cpufreq(unsigned int cpunum); + /* * There's probably some way to get time from Linux than gettimeofday(). What @@ -301,81 +306,163 @@ uv_err_t uv_uptime(double* uptime) { uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { - unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), - multiplier = ((uint64_t)1000L / ticks), cpuspeed; - int numcpus = 0, i = 0; - unsigned 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; - uv_cpu_info_t* cpu_info; - - 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); - } + unsigned int numcpus; + uv_cpu_info_t* ci; - *cpu_infos = (uv_cpu_info_t*)malloc(numcpus * sizeof(uv_cpu_info_t)); - if (!(*cpu_infos)) { - return uv__new_artificial_error(UV_ENOMEM); - } + *cpu_infos = NULL; + *count = 0; + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + assert(numcpus != (unsigned int) -1); + assert(numcpus != 0); + + ci = calloc(numcpus, sizeof(*ci)); + if (ci == NULL) + return uv__new_sys_error(ENOMEM); + + read_speeds(numcpus, ci); + read_models(numcpus, ci); + read_times(numcpus, ci); + + *cpu_infos = ci; *count = numcpus; - cpu_info = *cpu_infos; - - 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 %lu %lu %lu %lu %*s %lu", - &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); - } - - cpu_info->cpu_times.user = ticks_user * multiplier; - cpu_info->cpu_times.nice = ticks_nice * multiplier; - cpu_info->cpu_times.sys = ticks_sys * multiplier; - cpu_info->cpu_times.idle = ticks_idle * multiplier; - cpu_info->cpu_times.irq = ticks_intr * multiplier; - - cpu_info->model = strdup(model); - cpu_info->speed = cpuspeed; - - cpu_info++; + return uv_ok_; +} + + +static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) { + unsigned int num; + + for (num = 0; num < numcpus; num++) + ci[num].speed = read_cpufreq(num) / 1000; +} + + +static void read_models(unsigned int numcpus, uv_cpu_info_t* ci) { +#if defined(__i386__) || defined(__x86_64__) + static const char marker[] = "model name\t: "; +#elif defined(__arm__) + static const char marker[] = "Processor\t: "; +#elif defined(__mips__) + static const char marker[] = "cpu model\t\t: "; +#else +# warning uv_cpu_info() is not supported on this architecture. + static const char marker[] = "(dummy)"; +#endif + unsigned int num; + char buf[1024]; + char* model; + FILE* fp; + + fp = fopen("/proc/cpuinfo", "r"); + if (fp == NULL) + return; + + num = 0; + + while (fgets(buf, sizeof(buf), fp)) { + if (num >= numcpus) + break; + + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + + model = buf + sizeof(marker) - 1; + model = strndup(model, strlen(model) - 1); /* strip newline */ + ci[num++].model = model; + } + fclose(fp); +} + + +static void read_times(unsigned int numcpus, uv_cpu_info_t* ci) { + unsigned long clock_ticks; + struct uv_cpu_times_s ts; + unsigned long user; + unsigned long nice; + unsigned long sys; + unsigned long idle; + unsigned long dummy; + unsigned long irq; + unsigned int num; + unsigned int len; + char buf[1024]; + FILE* fp; + + clock_ticks = sysconf(_SC_CLK_TCK); + assert(clock_ticks != (unsigned long) -1); + assert(clock_ticks != 0); + + fp = fopen("/proc/stat", "r"); + if (fp == NULL) + return; + + if (!fgets(buf, sizeof(buf), fp)) + abort(); + + num = 0; + + while (fgets(buf, sizeof(buf), fp)) { + if (num >= numcpus) + break; + + if (strncmp(buf, "cpu", 3)) + break; + + /* skip "cpu " marker */ + { + unsigned int n = num; + for (len = sizeof("cpu0"); n /= 10; len++); + assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num); } - fclose(fpStat); + + /* Line contains user, nice, system, idle, iowait, irq, softirq, steal, + * guest, guest_nice but we're only interested in the first four + irq. + * + * Don't use %*s to skip fields or %ll to read straight into the uint64_t + * fields, they're not allowed in C89 mode. + */ + if (6 != sscanf(buf + len, + "%lu %lu %lu %lu %lu %lu", + &user, + &nice, + &sys, + &idle, + &dummy, + &irq)) + abort(); + + ts.user = clock_ticks * user; + ts.nice = clock_ticks * nice; + ts.sys = clock_ticks * sys; + ts.idle = clock_ticks * idle; + ts.irq = clock_ticks * irq; + ci[num++].cpu_times = ts; } + fclose(fp); +} - return uv_ok_; + +static unsigned long read_cpufreq(unsigned int cpunum) { + unsigned long val; + char buf[1024]; + FILE* fp; + + snprintf(buf, + sizeof(buf), + "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", + cpunum); + + fp = fopen(buf, "r"); + if (fp == NULL) + return 0; + + val = 0; + fscanf(fp, "%lu", &val); + fclose(fp); + + return val; } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 4d54e043ab..4033064029 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -205,26 +205,26 @@ static void uv__process_close_stream(uv_stdio_container_t* container) { static void uv__process_child_init(uv_process_options_t options, int stdio_count, int* pipes) { - int i; + int fd; if (options.flags & UV_PROCESS_DETACHED) { setsid(); } /* Dup fds */ - for (i = 0; i < stdio_count; i++) { + for (fd = 0; fd < stdio_count; fd++) { /* * stdin has swapped ends of pipe * (it's the only one readable stream) */ - int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2]; - int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1]; + int close_fd = fd == 0 ? pipes[fd * 2 + 1] : pipes[fd * 2]; + int use_fd = fd == 0 ? pipes[fd * 2] : pipes[fd * 2 + 1]; if (use_fd >= 0) { close(close_fd); - } else if (i < 3) { + } else if (fd < 3) { /* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */ - use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR); + use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR); if (use_fd < 0) { perror("failed to open stdio"); @@ -234,12 +234,15 @@ static void uv__process_child_init(uv_process_options_t options, continue; } - if (i != use_fd) { - dup2(use_fd, i); + if (fd != use_fd) { + dup2(use_fd, fd); close(use_fd); } else { uv__cloexec(use_fd, 0); } + + if (fd <= 2) + uv__nonblock(fd, 0); } if (options.cwd && chdir(options.cwd)) { diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 284643e4a3..ce8a1c1855 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -186,9 +186,6 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) { if (errno == EAGAIN || errno == EWOULDBLOCK) { /* No problem. */ return; - } else if (errno == EMFILE) { - /* TODO special trick. unlock reserved socket, accept, close. */ - return; } else if (errno == ECONNABORTED) { /* ignore */ continue; diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c index 233be82514..e6db3b5167 100644 --- a/deps/uv/src/unix/tcp.c +++ b/deps/uv/src/unix/tcp.c @@ -310,7 +310,10 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { } #endif -#ifdef TCP_KEEPALIVE + /* Solaris/SmartOS, if you don't support keep-alive, + * then don't advertise it in your system headers... + */ +#if defined(TCP_KEEPALIVE) && !defined(__sun) if (enable && setsockopt(handle->fd, IPPROTO_TCP, TCP_KEEPALIVE, diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index 79fb655c0f..5b47c2023b 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "uv.h" @@ -40,10 +41,21 @@ static uv_once_t uv_init_guard_ = UV_ONCE_INIT; static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT; +static void uv__crt_invalid_parameter_handler(const wchar_t* expression, + const wchar_t* function, const wchar_t * file, unsigned int line, + uintptr_t reserved) { + /* No-op. */ +} + + static void uv_init(void) { /* Tell Windows that we will handle critical errors. */ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); + SEM_NOOPENFILEERRORBOX); + + /* Tell the CRT to not exit the application when an invalid parameter is */ + /* passed. The main issue is that invalid FDs will trigger this behavior. */ + _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler); /* Fetch winapi function pointers. This must be done first because other */ /* intialization code might need these function pointers to be loaded. */ diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 340bcdcb3f..d290ce2e7f 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -1113,6 +1113,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { } else if (arg == 49) { /* Default background color */ bg_color = 0; + bg_bright = 0; } else if (arg >= 90 && arg <= 97) { /* Set bold foreground color */