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
This commit is contained in:
Saúl Ibarra Corretgé 2014-02-25 09:35:27 +01:00
parent 2f58bb6018
commit 7ad8f74302
5 changed files with 25 additions and 12 deletions

View File

@ -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,

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}