Commit 6781bae7 authored by Jérémy Lal's avatar Jérémy Lal

Imported Upstream version 0.6.10~dfsg1

parent 721f0239
......@@ -258,3 +258,6 @@ Michael Bernstein <michaelrbernstein@gmail.com>
Guillermo Rauch <rauchg@gmail.com>
Dan Williams <dan@igniter.com>
Brandon Benvie <brandon@bbenvie.com>
Nicolas LaCasse <nlacasse@borderstylo.com>
Dan VerWeire <dverweire@gmail.com>
Matthew Fitzsimmons <matt@joyent.com>
2012.01.19, Version 0.6.8 (stable)
2012.02.02, Version 0.6.10 (stable)
* Update V8 to 3.6.6.20
* Add npm msysgit bash shim to msi installer (isaacs)
* buffers: fix intermittent out of bounds error (Ben Noordhuis)
* buffers: honor length argument in base64 decoder (Ben Noordhuis)
* windows: Fix path.exists regression (Bert Belder)
* Make QueryString.parse run faster (Philip Tellis)
* http: avoid freeing http-parser objects too early (koichik)
* timers: add v0.4 compatibility hack (Ben Noordhuis)
* Proper EPERM error code support (Igor Zinkovsky, Brandon Philips)
* dgram: Implement udp multicast methods on windows (Bert Belder)
2012.01.27, Version 0.6.9 (stable), f19e20d33f57c4d2853aaea7d2724d44f3b0012f
* dgram: Bring back missing functionality for Unix (Dan VerWeire, Roman Shtylman, Ben Noordhuis)
- Note: Windows UDP support not yet complete.
* http: Fix parser memory leak (koichik)
* zlib: Fix #2365 crashes on invalid input (Nicolas LaCasse)
* module: fix --debug-brk on symlinked scripts (Fedor Indutny)
* Documentation Restyling (Matthew Fitzsimmons)
* Update npm to 1.1.0-3 (isaacs)
* Windows: fix regression in stat() calls to C:\ (Bert Belder)
2012.01.19, Version 0.6.8 (stable), d18cebaf8a7ac701dabd71a3aa4eb0571db6a645
* Update V8 to 3.6.6.19
......@@ -20,6 +61,8 @@
* fix segfault #2473
* #2521 60% improvement in fs.stat on Windows (Igor Zinkovsky)
2012.01.06, Version 0.6.7 (stable), d5a189acef14a851287ee555f7a39431fe276e1c
......
......@@ -91,23 +91,33 @@ website_files = \
out/doc/sh_main.js \
out/doc/sh_javascript.min.js \
out/doc/sh_vim-dark.css \
out/doc/sh.css \
out/doc/logo.png \
out/doc/sponsored.png \
out/doc/favicon.ico \
out/doc/pipe.css \
out/doc/about/index.html \
out/doc/close-downloads.png \
out/doc/community/index.html \
out/doc/community/not-invented-here.png \
out/doc/logos/index.html \
out/doc/microsoft-logo.png \
out/doc/ryan-speaker.jpg \
out/doc/download-logo.png \
out/doc/ebay-logo.png \
out/doc/footer-logo-alt.png \
out/doc/footer-logo.png \
out/doc/icons-interior.png \
out/doc/icons.png \
out/doc/home-icons.png \
out/doc/joyent-logo_orange_nodeorg-01.png \
out/doc/linkedin-logo.png \
out/doc/logos/index.html \
out/doc/logo-light.png \
out/doc/mac_osx_nodejs_installer_logo.png \
out/doc/microsoft-logo.png \
out/doc/platform-icons.png \
out/doc/ryan-speaker.jpg \
out/doc/sponsored.png \
out/doc/twitter-bird.png \
out/doc/community-icons.png \
out/doc/yahoo-logo.png
doc docs: out/Release/node $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs)
......
......@@ -153,7 +153,6 @@
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
'MACOSX_DEPLOYMENT_TARGET': '10.4', # -mmacosx-version-min=10.4
'PREBINDING': 'NO', # No -Wl,-prebind
'USE_HEADERMAP': 'NO',
'OTHER_CFLAGS': [
......
......@@ -45,12 +45,12 @@ if __name__ == '__main__':
# There's a bug with windows which doesn't allow this feature.
if sys.platform != 'win32':
# Tell gyp to write the Makefiles into output_dir
args.extend(['--generator-output', output_dir])
# Tell make to write its output into the same dir
args.extend(['-Goutput_dir=' + output_dir])
# Create Makefiles, not XCode projects
args.extend('-f make'.split())
args.append('-Dtarget_arch=ia32')
args.append('-Dcomponent=static_library')
......
......@@ -115,7 +115,9 @@ typedef intptr_t ssize_t;
XX( 45, EAISOCKTYPE, "") \
XX( 46, ESHUTDOWN, "") \
XX( 47, EEXIST, "file already exists") \
XX( 48, ESRCH, "no such process")
XX( 48, ESRCH, "no such process") \
XX( 49, ENAMETOOLONG, "name too long") \
XX( 50, EPERM, "operation not permitted")
#define UV_ERRNO_GEN(val, name, s) UV_##name = val,
......@@ -200,6 +202,9 @@ typedef struct uv_work_s uv_work_t;
UV_EXTERN uv_loop_t* uv_loop_new(void);
UV_EXTERN void uv_loop_delete(uv_loop_t*);
/* This is a debugging tool. It's NOT part of the official API. */
UV_EXTERN int uv_loop_refcount(const uv_loop_t*);
/*
* Returns the default loop.
......@@ -628,6 +633,59 @@ UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr, const char* interface_addr,
uv_membership membership);
/*
* Set IP multicast loop flag. Makes multicast packets loop back to
* local sockets.
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* on 1 for on, 0 for off
*
* Returns:
* 0 on success, -1 on error.
*/
UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
/*
* Set the multicast ttl
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* ttl 1 through 255
*
* Returns:
* 0 on success, -1 on error.
*/
UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
/*
* Set broadcast on or off
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* on 1 for on, 0 for off
*
* Returns:
* 0 on success, -1 on error.
*/
UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
/*
* Set the time to live
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* ttl 1 through 255
*
* Returns:
* 0 on success, -1 on error.
*/
UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
/*
* Send data. If the socket has not previously been bound with `uv_udp_bind`
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
......
......@@ -63,12 +63,6 @@ void uv__next(EV_P_ ev_idle* watcher, int revents);
static void uv__finish_close(uv_handle_t* handle);
#ifndef __GNUC__
#define __attribute__(a)
#endif
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv_udp_t* udp;
uv_async_t* async;
......@@ -181,6 +175,11 @@ void uv_loop_delete(uv_loop_t* loop) {
}
int uv_loop_refcount(const uv_loop_t* loop) {
return ev_loop_refcount(loop->ev);
}
uv_loop_t* uv_default_loop(void) {
if (!default_loop_ptr) {
default_loop_ptr = &default_loop_struct;
......
......@@ -59,6 +59,7 @@ void uv_fatal_error(const int errorno, const char* syscall) {
uv_err_code uv_translate_sys_error(int sys_errno) {
switch (sys_errno) {
case 0: return UV_OK;
case EPERM: return UV_EPERM;
case ENOSYS: return UV_ENOSYS;
case ENOTSOCK: return UV_ENOTSOCK;
case ENOENT: return UV_ENOENT;
......@@ -71,6 +72,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case EFAULT: return UV_EFAULT;
case EMFILE: return UV_EMFILE;
case EMSGSIZE: return UV_EMSGSIZE;
case ENAMETOOLONG: return UV_ENAMETOOLONG;
case EINVAL: return UV_EINVAL;
case ECONNREFUSED: return UV_ECONNREFUSED;
case EADDRINUSE: return UV_EADDRINUSE;
......
......@@ -251,7 +251,6 @@ void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
pipe = watcher->data;
assert(pipe->type == UV_NAMED_PIPE);
assert(pipe->pipe_fname != NULL);
sockfd = uv__accept(pipe->fd, (struct sockaddr *)&saddr, sizeof saddr);
if (sockfd == -1) {
......
......@@ -120,8 +120,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
struct stat s;
if (file < 0) {
uv__set_sys_error(NULL, EINVAL); /* XXX Need loop? */
return -1;
return UV_UNKNOWN_HANDLE;
}
if (isatty(file)) {
......@@ -129,8 +128,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
}
if (fstat(file, &s)) {
uv__set_sys_error(NULL, errno); /* XXX Need loop? */
return -1;
return UV_UNKNOWN_HANDLE;
}
if (!S_ISSOCK(s.st_mode) && !S_ISFIFO(s.st_mode)) {
......
......@@ -42,6 +42,10 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
static void uv__udp_watcher_start(uv_udp_t* handle, ev_io* w) {
int flags;
if (ev_is_active(w)) {
return;
}
assert(w == &handle->read_watcher
|| w == &handle->write_watcher);
......@@ -51,17 +55,23 @@ static void uv__udp_watcher_start(uv_udp_t* handle, ev_io* w) {
ev_set_cb(w, uv__udp_io);
ev_io_set(w, handle->fd, flags);
ev_io_start(handle->loop->ev, w);
ev_unref(handle->loop->ev);
}
void uv__udp_watcher_stop(uv_udp_t* handle, ev_io* w) {
int flags;
if (!ev_is_active(w)) {
return;
}
assert(w == &handle->read_watcher
|| w == &handle->write_watcher);
flags = (w == &handle->read_watcher ? EV_READ : EV_WRITE);
ev_ref(handle->loop->ev);
ev_io_stop(handle->loop->ev, w);
ev_io_set(w, -1, flags);
ev_set_cb(w, NULL);
......@@ -324,6 +334,28 @@ static int uv__bind(uv_udp_t* handle,
goto out;
}
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
uv__set_sys_error(handle->loop, errno);
goto out;
}
/* On the BSDs, SO_REUSEADDR lets you reuse an address that's in the TIME_WAIT
* state (i.e. was until recently tied to a socket) while SO_REUSEPORT lets
* multiple processes bind to the same address. Yes, it's something of a
* misnomer but then again, SO_REUSEADDR was already taken.
*
* None of the above applies to Linux: SO_REUSEADDR implies SO_REUSEPORT on
* Linux and hence it does not have SO_REUSEPORT at all.
*/
#ifdef SO_REUSEPORT
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof yes) == -1) {
uv__set_sys_error(handle->loop, errno);
goto out;
}
#endif
if (flags & UV_UDP_IPV6ONLY) {
#ifdef IPV6_V6ONLY
yes = 1;
......@@ -332,7 +364,7 @@ static int uv__bind(uv_udp_t* handle,
goto out;
}
#else
uv__set_sys_error((uv_handle_t*)handle, ENOTSUP);
uv__set_sys_error(handle->loop, ENOTSUP);
goto out;
#endif
}
......@@ -494,8 +526,55 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
}
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
int* namelen) {
#define X(name, level, option) \
int uv_udp_set_##name(uv_udp_t* handle, int flag) { \
if (setsockopt(handle->fd, level, option, &flag, sizeof(flag))) { \
uv__set_sys_error(handle->loop, errno); \
return -1; \
} \
return 0; \
}
X(broadcast, SOL_SOCKET, SO_BROADCAST)
X(ttl, IPPROTO_IP, IP_TTL)
#undef X
static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
#if __sun
char arg = val;
#else
int arg = val;
#endif
#if __sun
if (val < 0 || val > 255) {
uv__set_sys_error(handle->loop, EINVAL);
return -1;
}
#endif
if (setsockopt(handle->fd, IPPROTO_IP, option, &arg, sizeof(arg))) {
uv__set_sys_error(handle->loop, errno);
return -1;
}
return 0;
}
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, ttl);
}
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on);
}
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
socklen_t socklen;
int saved_errno;
int rv = 0;
......
......@@ -116,6 +116,11 @@ void uv_loop_delete(uv_loop_t* loop) {
}
int uv_loop_refcount(const uv_loop_t* loop) {
return loop->refs;
}
void uv_ref(uv_loop_t* loop) {
loop->refs++;
}
......
......@@ -69,7 +69,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_SUCCESS: return UV_OK;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
case ERROR_ACCESS_DENIED: return UV_EACCES;
case ERROR_ACCESS_DENIED: return UV_EPERM;
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
......@@ -94,6 +94,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case WSAEMSGSIZE: return UV_EMSGSIZE;
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
case WSAENETUNREACH: return UV_ENETUNREACH;
case WSAENOBUFS: return UV_ENOBUFS;
case ERROR_OUTOFMEMORY: return UV_ENOMEM;
case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
case WSAENOTCONN: return UV_ENOTCONN;
......
......@@ -489,70 +489,61 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
}
void fs__stat(uv_fs_t* req, const wchar_t* path) {
HANDLE file;
WIN32_FIND_DATAW ent;
static void fs__stat(uv_fs_t* req, const wchar_t* path) {
HANDLE handle;
int result;
BY_HANDLE_FILE_INFORMATION info;
req->ptr = NULL;
file = FindFirstFileExW(path, FindExInfoStandard, &ent,
FindExSearchNameMatch, NULL, 0);
if (file == INVALID_HANDLE_VALUE) {
handle = CreateFileW(path,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
return;
}
FindClose(file);
if (ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
ent.dwReserved0 == IO_REPARSE_TAG_SYMLINK) {
fs__open(req, path, _O_RDONLY, 0);
if (req->result != -1) {
result = _fstati64(req->result, &req->stat);
_close(req->result);
if (result != -1) {
req->ptr = &req->stat;
}
SET_REQ_RESULT(req, result);
}
if (!GetFileInformationByHandle(handle, &info)) {
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
CloseHandle(handle);
return;
}
req->stat.st_ino = 0;
req->stat.st_uid = 0;
req->stat.st_gid = 0;
req->stat.st_mode = 0;
req->stat.st_rdev = 0;
req->stat.st_dev = 0;
req->stat.st_nlink = 1;
memset(&req->stat, 0, sizeof req->stat);
/* TODO: set st_dev and st_ino? */
if (ent.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) {
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
req->stat.st_mode |= (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6));
} else {
req->stat.st_mode |= ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3) +
((_S_IREAD|_S_IWRITE) >> 6));
}
if (ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
req->stat.st_mode |= _S_IFDIR;
} else {
req->stat.st_mode |= _S_IFREG;
}
uv_filetime_to_time_t(&ent.ftLastWriteTime, &(req->stat.st_mtime));
uv_filetime_to_time_t(&ent.ftLastAccessTime, &(req->stat.st_atime));
uv_filetime_to_time_t(&ent.ftCreationTime, &(req->stat.st_ctime));
uv_filetime_to_time_t(&info.ftLastWriteTime, &(req->stat.st_mtime));
uv_filetime_to_time_t(&info.ftLastAccessTime, &(req->stat.st_atime));
uv_filetime_to_time_t(&info.ftCreationTime, &(req->stat.st_ctime));
req->stat.st_size = ((int64_t)ent.nFileSizeHigh << 32) +
(int64_t)ent.nFileSizeLow;
req->stat.st_size = ((int64_t) info.nFileSizeHigh << 32) +
(int64_t) info.nFileSizeLow;
req->stat.st_nlink = info.nNumberOfLinks;
req->ptr = &req->stat;
req->result = 0;
CloseHandle(handle);
}
......
......@@ -1069,13 +1069,26 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
bg_bright = 0;
} else if (arg == 1) {
/* Bright */
/* Foreground bright on */
fg_bright = 1;
} else if (arg == 2) {
/* Both bright off */
fg_bright = 0;
bg_bright = 0;
} else if (arg == 5) {
/* Background bright on */
bg_bright = 1;
} else if (arg == 21 || arg == 22) {
/* Bright off. */
/* Foreground bright off */
fg_bright = 0;
} else if (arg == 25) {
/* Background bright off */
bg_bright = 0;
} else if (arg >= 30 && arg <= 37) {
/* Set foreground color */
fg_color = arg - 30;
......@@ -1091,6 +1104,17 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
} else if (arg == 49) {
/* Default background color */
bg_color = 0;
} else if (arg >= 90 && arg <= 97) {
/* Set bold foreground color */
fg_bright = 1;
fg_color = arg - 90;
} else if (arg >= 100 && arg <= 107) {
/* Set bold background color */
bg_bright = 1;
bg_color = arg - 100;
}
}
......
......@@ -166,9 +166,9 @@ static int uv__bind(uv_udp_t* handle,
struct sockaddr* addr,
int addrsize,
unsigned int flags) {
DWORD err;
int r;
SOCKET sock;
DWORD no = 0, yes = 1;
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
......@@ -190,7 +190,6 @@ static int uv__bind(uv_udp_t* handle,
}
if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
DWORD off = 0;
/* On windows IPV6ONLY is on by default. */
/* If the user doesn't specify it libuv turns it off. */
......@@ -200,14 +199,22 @@ static int uv__bind(uv_udp_t* handle,
setsockopt(sock,
IPPROTO_IPV6,
IPV6_V6ONLY,
(const char*) &off,
sizeof off);
(char*) &no,
sizeof no);
}
r = bind(handle->socket, addr, addrsize);
r = setsockopt(sock,
SOL_SOCKET,
SO_REUSEADDR,
(char*) &yes,
sizeof yes);
if (r == SOCKET_ERROR) {
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
r = bind(handle->socket, addr, addrsize);
if (r == SOCKET_ERROR) {
err = WSAGetLastError();
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
......@@ -244,15 +251,6 @@ int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
}
int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
const char* interface_addr, uv_membership membership) {
/* not implemented yet */
uv__set_artificial_error(handle->loop, UV_ENOSYS);
return -1;
}
static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
uv_req_t* req;
uv_buf_t buf;
......@@ -578,3 +576,115 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
DECREASE_PENDING_REQ_COUNT(handle);
}
int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
const char* interface_addr, uv_membership membership) {
int optname;
struct ip_mreq mreq;
/* If the socket is unbound, bind to inaddr_any. */
if (!(handle->flags & UV_HANDLE_BOUND) &&
uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
return -1;
}
if (handle->flags & UV_HANDLE_IPV6) {
uv__set_artificial_error(handle->loop, UV_ENOSYS);
return -1;
}
memset(&mreq, 0, sizeof mreq);
if (interface_addr) {
mreq.imr_interface.s_addr = inet_addr(interface_addr);
} else {
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
switch (membership) {
case UV_JOIN_GROUP:
optname = IP_ADD_MEMBERSHIP;
break;
case UV_LEAVE_GROUP:
optname = IP_DROP_MEMBERSHIP;
break;
default:
uv__set_artificial_error(handle->loop, UV_EFAULT);
return -1;
}
if (setsockopt(handle->socket,
IPPROTO_IP,
optname,
(char*) &mreq,
sizeof mreq) == SOCKET_ERROR) {
uv__set_sys_error(handle->loop, WSAGetLastError());
return -1;
}
return 0;
}
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {