uv-unix: uv_pipe_bind: raise UV_EINVAL if pipe already bound

Fixes failing test pipe_bind_error_inval.
This commit is contained in:
Ben Noordhuis 2011-07-21 18:16:07 +02:00
parent 580a5b464f
commit fb42f82df6

View File

@ -1788,29 +1788,40 @@ int uv_pipe_init(uv_pipe_t* handle) {
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
struct sockaddr_un sun;
const char* pipe_fname;
int saved_errno;
int sockfd;
int status;
int bound;
saved_errno = errno;
pipe_fname = NULL;
sockfd = -1;
status = -1;
bound = 0;
/* Already bound? */
if (handle->fd >= 0) {
uv_err_new_artificial((uv_handle_t*)handle, UV_EINVAL);
goto out;
}
/* Make a copy of the file name, it outlives this function's scope. */
if ((name = (const char*)strdup(name)) == NULL) {
if ((pipe_fname = strdup(name)) == NULL) {
uv_err_new((uv_handle_t*)handle, ENOMEM);
goto out;
}
/* We've got a copy, don't touch the original any more. */
name = NULL;
if ((sockfd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
uv_err_new((uv_handle_t*)handle, errno);
goto out;
}
memset(&sun, 0, sizeof sun);
uv__strlcpy(sun.sun_path, name, sizeof(sun.sun_path));
uv__strlcpy(sun.sun_path, pipe_fname, sizeof(sun.sun_path));
sun.sun_family = AF_UNIX;
if (bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
@ -1827,7 +1838,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
* Try to re-purpose the socket. This is a potential race window.
*/
if (errno != EADDRINUSE
|| unlink(name) == -1
|| unlink(pipe_fname) == -1
|| bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
uv_err_new((uv_handle_t*)handle, errno);
goto out;
@ -1837,7 +1848,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
bound = 1;
/* Success. */
handle->pipe_fname = name; /* Is a strdup'ed copy. */
handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
handle->fd = sockfd;
status = 0;
@ -1846,10 +1857,11 @@ out:
if (status) {
if (bound) {
/* unlink() before close() to avoid races. */
unlink(name);
assert(pipe_fname != NULL);
unlink(pipe_fname);
}
uv__close(sockfd);
free((void*)name);
free((void*)pipe_fname);
}
errno = saved_errno;