| 545 | } |
| 546 | |
| 547 | int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) { |
| 548 | #ifndef _WIN32 |
| 549 | int blocking = (c->flags & REDIS_BLOCK); |
| 550 | struct sockaddr_un *sa; |
| 551 | long timeout_msec = -1; |
| 552 | |
| 553 | if (redisCreateSocket(c,AF_UNIX) < 0) |
| 554 | return REDIS_ERR; |
| 555 | if (redisSetBlocking(c,0) != REDIS_OK) |
| 556 | return REDIS_ERR; |
| 557 | |
| 558 | c->connection_type = REDIS_CONN_UNIX; |
| 559 | if (c->unix_sock.path != path) { |
| 560 | hi_free(c->unix_sock.path); |
| 561 | |
| 562 | c->unix_sock.path = hi_strdup(path); |
| 563 | if (c->unix_sock.path == NULL) |
| 564 | goto oom; |
| 565 | } |
| 566 | |
| 567 | if (timeout) { |
| 568 | if (redisContextUpdateConnectTimeout(c, timeout) == REDIS_ERR) |
| 569 | goto oom; |
| 570 | } else { |
| 571 | hi_free(c->connect_timeout); |
| 572 | c->connect_timeout = NULL; |
| 573 | } |
| 574 | |
| 575 | if (redisContextTimeoutMsec(c,&timeout_msec) != REDIS_OK) |
| 576 | return REDIS_ERR; |
| 577 | |
| 578 | /* Don't leak sockaddr if we're reconnecting */ |
| 579 | if (c->saddr) hi_free(c->saddr); |
| 580 | |
| 581 | sa = (struct sockaddr_un*)(c->saddr = hi_malloc(sizeof(struct sockaddr_un))); |
| 582 | if (sa == NULL) |
| 583 | goto oom; |
| 584 | |
| 585 | c->addrlen = sizeof(struct sockaddr_un); |
| 586 | sa->sun_family = AF_UNIX; |
| 587 | strncpy(sa->sun_path, path, sizeof(sa->sun_path) - 1); |
| 588 | if (connect(c->fd, (struct sockaddr*)sa, sizeof(*sa)) == -1) { |
| 589 | if (errno == EINPROGRESS && !blocking) { |
| 590 | /* This is ok. */ |
| 591 | } else { |
| 592 | if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) |
| 593 | return REDIS_ERR; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | /* Reset socket to be blocking after connect(2). */ |
| 598 | if (blocking && redisSetBlocking(c,1) != REDIS_OK) |
| 599 | return REDIS_ERR; |
| 600 | |
| 601 | c->flags |= REDIS_CONNECTED; |
| 602 | return REDIS_OK; |
| 603 | #else |
| 604 | /* We currently do not support Unix sockets for Windows. */ |
no test coverage detected