From 7ad8f74302f88e85142d6af50c4178d13a2fd3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Tue, 25 Feb 2014 09:35:27 +0100 Subject: [PATCH] unix, windows: set required size on UV_ENOBUFS When the supplied buffer is not big enough and UV_ENOBUFS is returned, hint the user about the required size by setting the len paramemeter to the required value. Applies to: - uv_pipe_getsockname - uv_fs_event_getpath - uv_fs_poll_getpath --- include/uv.h | 19 +++++++++++++------ src/fs-poll.c | 2 +- src/unix/pipe.c | 2 +- src/uv-common.c | 2 +- src/win/pipe.c | 12 +++++++++--- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/include/uv.h b/include/uv.h index fb704f98f..607f5c88d 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1203,9 +1203,12 @@ UV_EXTERN void uv_pipe_connect(uv_connect_t* req, * * A preallocated buffer must be provided. The len parameter holds the * length of the buffer and it's set to the number of bytes written to the - * buffer on output. + * buffer on output. If the buffer is not big enough UV_ENOBUFS will be + * returned and len will contain the required size. */ -UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len); +UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, + char* buf, + size_t* len); /* * This setting applies to Windows only. @@ -1934,9 +1937,11 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle, UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle); /* - * Get the path befing monitored by the handle. The buffer must be preallocated + * Get the path being monitored by the handle. The buffer must be preallocated * by the user. Returns 0 on success or an error code < 0 in case of failure. - * On sucess, `buf` will contain the path and `len` its length. + * On sucess, `buf` will contain the path and `len` its length. If the buffer + * is not big enough UV_ENOBUFS will be returned and len will be set to the + * required size. */ UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len); @@ -2044,9 +2049,11 @@ UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); /* - * Get the path befing monitored by the handle. The buffer must be preallocated + * Get the path being monitored by the handle. The buffer must be preallocated * by the user. Returns 0 on success or an error code < 0 in case of failure. - * On sucess, `buf` will contain the path and `len` its length. + * On sucess, `buf` will contain the path and `len` its length. If the buffer + * is not big enough UV_ENOBUFS will be returned and len will be set to the + * required size. */ UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, diff --git a/src/fs-poll.c b/src/fs-poll.c index b3c7ac99d..abde00302 100644 --- a/src/fs-poll.c +++ b/src/fs-poll.c @@ -132,7 +132,7 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len) { required_len = strlen(ctx->path) + 1; if (required_len > *len) { - *len = 0; + *len = required_len; return UV_ENOBUFS; } diff --git a/src/unix/pipe.c b/src/unix/pipe.c index 2713abf4a..34c118b77 100644 --- a/src/unix/pipe.c +++ b/src/unix/pipe.c @@ -233,7 +233,7 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { if (addrlen > *len) { - *len = 0; + *len = addrlen; return UV_ENOBUFS; } diff --git a/src/uv-common.c b/src/uv-common.c index 26a8df08d..2a6316a87 100644 --- a/src/uv-common.c +++ b/src/uv-common.c @@ -455,7 +455,7 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) { required_len = strlen(handle->path) + 1; if (required_len > *len) { - *len = 0; + *len = required_len; return UV_ENOBUFS; } diff --git a/src/win/pipe.c b/src/win/pipe.c index 73a002640..69c5cde62 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -1779,8 +1779,10 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { if (nt_status == STATUS_BUFFER_OVERFLOW) { name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; name_info = malloc(name_size); - if (!name_info) - uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + if (!name_info) { + *len = 0; + return UV_ENOMEM; + } nt_status = pNtQueryInformationFile(handle->handle, &io_status, @@ -1790,6 +1792,7 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { } if (nt_status != STATUS_SUCCESS) { + *len = 0; err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status)); goto error; } @@ -1804,6 +1807,7 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { } if (name_len == 0) { + *len = 0; err = 0; goto error; } @@ -1820,10 +1824,12 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { NULL, NULL); if (!addrlen) { + *len = 0; err = uv_translate_sys_error(GetLastError()); goto error; } else if (pipe_prefix_len + addrlen + 1 > *len) { /* "\\\\.\\pipe" + name + '\0' */ + *len = pipe_prefix_len + addrlen + 1; err = UV_ENOBUFS; goto error; } @@ -1838,6 +1844,7 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { NULL, NULL); if (!addrlen) { + *len = 0; err = uv_translate_sys_error(GetLastError()); goto error; } @@ -1850,6 +1857,5 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) { error: free(name_info); - *len = 0; return err; }