Skip to content

Commit 6f08876

Browse files
authored
Merge 43598e4 into db633d1
2 parents db633d1 + 43598e4 commit 6f08876

4 files changed

Lines changed: 54 additions & 2 deletions

File tree

common/common.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5174,6 +5174,53 @@ char *xstrdup(const char *string)
51745174
return p;
51755175
}
51765176

5177+
/* Try to connect to addr, using select() for timeout since AF_UNIX won't timeout normally */
5178+
#ifndef WIN32
5179+
int select_connect(int fd, const struct sockaddr_un *addr, socklen_t addrlen, const time_t d_sec, const suseconds_t d_usec)
5180+
{
5181+
int rc;
5182+
int err = 0;
5183+
int flags = fcntl(fd, F_GETFL, 0);
5184+
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
5185+
5186+
rc = connect(fd, addr, addrlen);
5187+
if (rc == -1 && errno != EINPROGRESS) {
5188+
err = errno;
5189+
} else if (rc == -1) {
5190+
fd_set w_fds;
5191+
fd_set e_fds;
5192+
struct timeval tv;
5193+
5194+
FD_ZERO(&w_fds);
5195+
FD_SET(fd, &w_fds);
5196+
FD_ZERO(&e_fds);
5197+
FD_SET(fd, &e_fds);
5198+
5199+
tv.tv_sec = d_sec;
5200+
tv.tv_usec = d_usec;
5201+
5202+
rc = select(fd + 1, NULL, &w_fds, &e_fds, &tv);
5203+
5204+
if (rc < 0) {
5205+
err = errno;
5206+
} else if (rc == 0) {
5207+
err = ETIMEDOUT;
5208+
} else if (rc > 0) {
5209+
socklen_t len = sizeof(err);
5210+
getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
5211+
}
5212+
}
5213+
5214+
fcntl(fd, F_SETFL, flags);
5215+
5216+
if (err != 0) {
5217+
errno = err;
5218+
return -1;
5219+
}
5220+
return 0;
5221+
}
5222+
#endif
5223+
51775224
/* Read up to buflen bytes from fd and return the number of bytes
51785225
read. If no data is available within d_sec + d_usec, return 0.
51795226
On error, a value < 0 is returned (errno indicates error). */

drivers/upsdrvquery.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ udq_pipe_conn_t *upsdrvquery_connect(const char *sockfn) {
8181
return NULL;
8282
}
8383

84-
if (connect(conn->sockfd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
84+
if (select_connect(conn->sockfd, &sa, sizeof(sa), 1, 0) < 0) {
8585
if (nut_debug_level > 0 || nut_upsdrvquery_debug_level >= NUT_UPSDRVQUERY_DEBUG_LEVEL_CONNECT)
8686
upslog_with_errno(LOG_ERR, "connect to driver socket at %s", sockfn);
8787
close(conn->sockfd);

include/common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
#ifndef WIN32
6969
# include <syslog.h>
70+
# include <sys/un.h>
7071
#else /* WIN32 */
7172
# include <winsock2.h>
7273
# include <windows.h>
@@ -754,6 +755,7 @@ int match_regex_hex(const regex_t *preg, const int n);
754755

755756
/* Note: different method signatures instead of TYPE_FD_SER due to "const" */
756757
#ifndef WIN32
758+
int select_connect(int fd, const struct sockaddr_un *addr, socklen_t addrlen, const time_t d_sec, const suseconds_t d_usec);
757759
ssize_t select_read(const int fd, void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec);
758760
ssize_t select_write(const int fd, const void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec);
759761
#else /* WIN32 */

server/sstate.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,10 @@ TYPE_FD sstate_connect(upstype_t *ups)
215215
return ERROR_FD;
216216
}
217217

218-
ret = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
218+
ret = select_connect(fd, &sa, sizeof(sa), 1, 0);
219219

220220
if (ret < 0) {
221+
int err = errno;
221222
time_t now;
222223

223224
if (strstr(sa.sun_path, "/")) {
@@ -237,6 +238,8 @@ TYPE_FD sstate_connect(upstype_t *ups)
237238
return ERROR_FD;
238239

239240
ups->last_connfail = now;
241+
/* restore errno for logging */
242+
errno = err;
240243
if (strstr(ups->fn, "/")) {
241244
upslog_with_errno(LOG_ERR, "Can't connect to UPS [%s] (%s)",
242245
ups->name, ups->fn);

0 commit comments

Comments
 (0)