Skip to content

Commit

Permalink
uv: upgrade to v0.11.10
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Aug 24, 2013
1 parent 467e00e commit 8333859
Show file tree
Hide file tree
Showing 9 changed files with 385 additions and 134 deletions.
1 change: 0 additions & 1 deletion deps/uv/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ Kristian Evensen <kristian.evensen@gmail.com>
Nils Maier <maierman@web.de>
Nicholas Vavilov <vvnicholas@gmail.com>
Miroslav Bajtoš <miro.bajtos@gmail.com>
Elliot Saba <staticfloat@gmail.com>
Sean Silva <chisophugis@gmail.com>
Wynn Wilkes <wynnw@movenetworks.com>
Linus Mårtensson <linus.martensson@sonymobile.com>
Expand Down
20 changes: 19 additions & 1 deletion deps/uv/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
2013.08.24, Version 0.11.9 (Unstable)
2013.08.25, Version 0.11.10 (Unstable)

* windows: Re-implement uv_fs_stat. The st_ctime field now contains the change
time, not the creation time, like on unix systems. st_dev, st_ino, st_blocks
and st_blksize are now also filled out. (Bert Belder)

* linux: fix setsockopt(SO_REUSEPORT) error handling (Ben Noordhuis)

* windows: report uv_process_t exit code correctly (Bert Belder)

* windows: make uv_fs_chmod() report errors correctly (Bert Belder)

* windows: make some more NT apis available for libuv's internal use (Bert
Belder)

* windows: squelch some compiler warnings (Bert Belder)


2013.08.24, Version 0.11.9 (Unstable), a2d29b5b068cbac93dc16138fb30a74e2669daad

Changes since version 0.11.8:

Expand Down
91 changes: 53 additions & 38 deletions deps/uv/src/unix/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,53 @@ static void uv__udp_sendmsg(uv_loop_t* loop,
}


/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but it also lets you share
* the address and port with other processes.
*
* Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that
* are different from the BSDs. The address:port sharing part is taken care
* of by SO_REUSEADDR while SO_REUSEPORT enables fair load distribution. (If
* you wonder why you need to explicitly enable that, well, it's complicated.)
*
* Because we cannot rely on SO_REUSEPORT being available on Linux, it's not
* considered an error when the setsockopt() system call fails. Worst case,
* the program has sub-optimal load distribution characteristics but should
* otherwise run fine.
*/
static int uv__set_reuse(int fd) {
int yes;
#if defined(__linux__)
static int no_so_reuseport;

if (no_so_reuseport)
goto no_so_reuseport;

yes = 1;
if (setsockopt(fd, SOL_SOCKET, 15 /* SO_REUSEPORT */, &yes, sizeof(yes))) {
if (errno != EINVAL && errno != ENOPROTOOPT)
return -errno;
no_so_reuseport = 1;
}

no_so_reuseport:

yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
return -errno;
#elif defined(SO_REUSEPORT)
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
return -errno;
#else
yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
return -errno;
#endif

return 0;
}


static int uv__bind(uv_udp_t* handle,
int domain,
struct sockaddr* addr,
Expand Down Expand Up @@ -308,27 +355,9 @@ static int uv__bind(uv_udp_t* handle,
handle->io_watcher.fd = fd;
}

yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes) == -1) {
err = -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) {
err = -errno;
err = uv__set_reuse(fd);
if (err)
goto out;
}
#endif

if (flags & UV_UDP_IPV6ONLY) {
#ifdef IPV6_V6ONLY
Expand Down Expand Up @@ -464,29 +493,15 @@ int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags) {


int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int yes;
int err;

/* Check for already active socket. */
if (handle->io_watcher.fd != -1)
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */

yes = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes))
return -errno;

/* 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(sock, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof yes))
return -errno;
#endif
err = uv__set_reuse(sock);
if (err)
return err;

handle->io_watcher.fd = sock;
return 0;
Expand Down
2 changes: 1 addition & 1 deletion deps/uv/src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
#define UV_VERSION_PATCH 9
#define UV_VERSION_PATCH 10
#define UV_VERSION_IS_RELEASE 1


Expand Down
153 changes: 105 additions & 48 deletions deps/uv/src/win/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@

#define FILETIME_TO_TIMESPEC(ts, filetime) \
do { \
(ts).tv_sec = FILETIME_TO_TIME_T(filetime); \
(ts).tv_nsec = FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \
(ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \
(ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \
} while(0)

#define TIME_T_TO_FILETIME(time, filetime_ptr) \
Expand Down Expand Up @@ -241,7 +241,7 @@ static int is_path_dir(const WCHAR* path) {


INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
int64_t* target_len_ptr) {
uint64_t* target_len_ptr) {
char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
WCHAR *w_target;
Expand Down Expand Up @@ -809,56 +809,117 @@ void fs__readdir(uv_fs_t* req) {


INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
BY_HANDLE_FILE_INFORMATION info;
FILE_ALL_INFORMATION file_info;
FILE_FS_VOLUME_INFORMATION volume_info;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;

if (!GetFileInformationByHandle(handle, &info)) {
nt_status = pNtQueryInformationFile(handle,
&io_status,
&file_info,
sizeof file_info,
FileAllInformation);

/* Buffer overflow (a warning status code) is expected here. */
if (NT_ERROR(nt_status)) {
SetLastError(pRtlNtStatusToDosError(nt_status));
return -1;
}

/* TODO: set st_dev, st_rdev and st_ino to something meaningful. */
statbuf->st_ino = 0;
statbuf->st_dev = 0;
statbuf->st_rdev = 0;
nt_status = pNtQueryVolumeInformationFile(handle,
&io_status,
&volume_info,
sizeof volume_info,
FileFsVolumeInformation);

statbuf->st_gid = 0;
statbuf->st_uid = 0;
/* Buffer overflow (a warning status code) is expected here. */
if (NT_ERROR(nt_status)) {
SetLastError(pRtlNtStatusToDosError(nt_status));
return -1;
}

/* Todo: st_mode should probably always be 0666 for everyone. We might also
* want to report 0777 if the file is a .exe or a directory.
*
* Currently it's based on whether the 'readonly' attribute is set, which
* makes little sense because the semantics are so different: the 'read-only'
* flag is just a way for a user to protect against accidental deleteion, and
* serves no security purpose. Windows uses ACLs for that.
*
* Also people now use uv_fs_chmod() to take away the writable bit for good
* reasons. Windows however just makes the file read-only, which makes it
* impossible to delete the file afterwards, since read-only files can't be
* deleted.
*
* IOW it's all just a clusterfuck and we should think of something that
* makes slighty more sense.
*
* And uv_fs_chmod should probably just fail on windows or be a total no-op.
* There's nothing sensible it can do anyway.
*/
statbuf->st_mode = 0;

statbuf->st_blksize = 0;
statbuf->st_blocks = 0;

statbuf->st_flags = 0;
statbuf->st_gen = 0;

if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) {
return -1;
}
if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
statbuf->st_mode |= S_IFLNK;
} else if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0)
return -1;

} else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
statbuf->st_mode |= _S_IFDIR;
statbuf->st_size = 0;

} else {
statbuf->st_mode |= _S_IFREG;
statbuf->st_size = ((int64_t) info.nFileSizeHigh << 32) +
(int64_t) info.nFileSizeLow;
statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
}

if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
statbuf->st_mode |= (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6));
} else {
statbuf->st_mode |= ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3) +
((_S_IREAD|_S_IWRITE) >> 6));
}
if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)
statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6);
else
statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
((_S_IREAD | _S_IWRITE) >> 6);

FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime);
FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime);
FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime);
FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime);

statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart;

/* st_blocks contains the on-disk allocation size in 512-byte units. */
statbuf->st_blocks =
file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL;

FILETIME_TO_TIMESPEC(statbuf->st_mtim, info.ftLastWriteTime);
FILETIME_TO_TIMESPEC(statbuf->st_atim, info.ftLastAccessTime);
FILETIME_TO_TIMESPEC(statbuf->st_ctim, info.ftCreationTime);
FILETIME_TO_TIMESPEC(statbuf->st_birthtim, info.ftCreationTime);
statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks;

statbuf->st_nlink = (info.nNumberOfLinks <= SHRT_MAX) ?
(short) info.nNumberOfLinks : SHRT_MAX;
statbuf->st_dev = volume_info.VolumeSerialNumber;

/* The st_blksize is supposed to be the 'optimal' number of bytes for reading
* and writing to the disk. That is, for any definition of 'optimal' - it's
* supposed to at least avoid read-update-write behavior when writing to the
* disk.
*
* However nobody knows this and even fewer people actually use this value,
* and in order to fill it out we'd have to make another syscall to query the
* volume for FILE_FS_SECTOR_SIZE_INFORMATION.
*
* Therefore we'll just report a sensible value that's quite commonly okay
* on modern hardware.
*/
statbuf->st_blksize = 2048;

/* Todo: set st_flags to something meaningful. Also provide a wrapper for
* chattr(2).
*/
statbuf->st_flags = 0;

/* Windows has nothing sensible to say about these values, so they'll just
* remain empty.
*/
statbuf->st_gid = 0;
statbuf->st_uid = 0;
statbuf->st_rdev = 0;
statbuf->st_gen = 0;

return 0;
}
Expand Down Expand Up @@ -1069,25 +1130,24 @@ static void fs__chmod(uv_fs_t* req) {

static void fs__fchmod(uv_fs_t* req) {
int fd = req->fd;
int result;
HANDLE handle;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
FILE_BASIC_INFORMATION file_info;

VERIFY_FD(fd, req);

handle = (HANDLE)_get_osfhandle(fd);
handle = (HANDLE) _get_osfhandle(fd);

nt_status = pNtQueryInformationFile(handle,
&io_status,
&file_info,
sizeof file_info,
FileBasicInformation);

if (nt_status != STATUS_SUCCESS) {
result = -1;
goto done;
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
return;
}

if (req->mode & _S_IWRITE) {
Expand All @@ -1102,15 +1162,12 @@ static void fs__fchmod(uv_fs_t* req) {
sizeof file_info,
FileBasicInformation);

if (nt_status != STATUS_SUCCESS) {
result = -1;
goto done;
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
return;
}

result = 0;

done:
SET_REQ_RESULT(req, result);
SET_REQ_SUCCESS(req);
}


Expand Down
6 changes: 4 additions & 2 deletions deps/uv/src/win/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {

/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
int exit_code;
int64_t exit_code;
DWORD status;

assert(handle->exit_cb_pending);
Expand All @@ -755,7 +755,9 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
if (handle->spawn_error) {
/* Spawning failed. */
exit_code = uv_translate_sys_error(handle->spawn_error);
} else if (!GetExitCodeProcess(handle->process_handle, &status)) {
} else if (GetExitCodeProcess(handle->process_handle, &status)) {
exit_code = status;
} else {
/* Unable to to obtain the exit code. This should never happen. */
exit_code = uv_translate_sys_error(GetLastError());
}
Expand Down
Loading

0 comments on commit 8333859

Please sign in to comment.