}
-/*
- * Wrappers for read/write/recv/send that survive interruptions.
- */
-
-int safe_read(int fd, void *buf, int len)
-{
- int res;
-loop:
- res = read(fd, buf, len);
- if (res < 0 && errno == EINTR)
- goto loop;
- return res;
-}
-
-int safe_write(int fd, const void *buf, int len)
-{
- int res;
-loop:
- res = write(fd, buf, len);
- if (res < 0 && errno == EINTR)
- goto loop;
- return res;
-}
-
-int safe_recv(int fd, void *buf, int len, int flags)
-{
- int res;
-loop:
- res = recv(fd, buf, len, flags);
- if (res < 0 && errno == EINTR)
- goto loop;
- if (res < 0)
- log_noise("safe_recv(%d, %d) = %s", fd, len, strerror(errno));
- else if (cf_verbose > 2)
- log_noise("safe_recv(%d, %d) = %d", fd, len, res);
- return res;
-}
-
-int safe_send(int fd, const void *buf, int len, int flags)
-{
- int res;
-loop:
- res = send(fd, buf, len, flags);
- if (res < 0 && errno == EINTR)
- goto loop;
- if (res < 0)
- log_noise("safe_send(%d, %d) = %s", fd, len, strerror(errno));
- else if (cf_verbose > 2)
- log_noise("safe_send(%d, %d) = %d", fd, len, res);
- return res;
-}
-
-int safe_close(int fd)
-{
- int res;
-loop:
- /* by manpage, the close() could be interruptable
- although it seems that at least in linux it cannot happen */
-#ifndef WIN32
- res = close(fd);
-#else
- /* Pending(this is necessary to wait for FIN of a client.) */
- log_debug("closesocket(%d)",fd);
- res = closesocket(fd);
-#endif
- if (res < 0 && errno == EINTR)
- goto loop;
- return res;
-}
-
-int safe_recvmsg(int fd, struct msghdr *msg, int flags)
-{
- int res;
-loop:
- res = recvmsg(fd, msg, flags);
- if (res < 0 && errno == EINTR)
- goto loop;
- if (res < 0)
- log_warning("safe_recvmsg(%d, msg, %d) = %s", fd, flags, strerror(errno));
- else if (cf_verbose > 2)
- log_noise("safe_recvmsg(%d, msg, %d) = %d", fd, flags, res);
- return res;
-}
-
-int safe_sendmsg(int fd, const struct msghdr *msg, int flags)
-{
- int res;
- int msgerr_count = 0;
-loop:
- res = sendmsg(fd, msg, flags);
- if (res < 0 && errno == EINTR)
- goto loop;
-
- if (res < 0) {
- log_warning("safe_sendmsg(%d, msg[%d,%d], %d) = %s", fd,
- (int)msg->msg_iov[0].iov_len,
- (int)msg->msg_controllen,
- flags, strerror(errno));
-
- /* with ancillary data on blocking socket OSX returns
- * EMSGSIZE instead of blocking. try to solve it by waiting */
- if (errno == EMSGSIZE && msgerr_count < 20) {
- struct timeval tv = {1, 0};
- log_warning("trying to sleep a bit");
- select(0, NULL, NULL, NULL, &tv);
- msgerr_count++;
- goto loop;
- }
- } else if (cf_verbose > 2)
- log_noise("safe_sendmsg(%d, msg, %d) = %d", fd, flags, res);
- return res;
-}
-
-int safe_connect(int fd, const struct sockaddr *sa, socklen_t sa_len)
-{
- int res;
- char buf[128];
-loop:
- res = connect(fd, sa, sa_len);
- if (res < 0 && errno == EINTR)
- goto loop;
- if (res < 0 && (errno != EINPROGRESS || cf_verbose > 2))
- log_noise("connect(%d, %s) = %s", fd, sa2str(sa, buf, sizeof(buf)), strerror(errno));
- else if (cf_verbose > 2)
- log_noise("connect(%d, %s) = %d", fd, sa2str(sa, buf, sizeof(buf)), res);
- return res;
-}
-
-int safe_accept(int fd, struct sockaddr *sa, socklen_t *sa_len_p)
-{
- int res;
- char buf[128];
-loop:
- res = accept(fd, sa, sa_len_p);
- if (res < 0 && errno == EINTR)
- goto loop;
- if (res < 0)
- log_noise("safe_accept(%d) = %s", fd, strerror(errno));
- else if (cf_verbose > 2)
- log_noise("safe_accept(%d) = %d (%s)", fd, res, sa2str(sa, buf, sizeof(buf)));
- return res;
-}
-
/*
* Load a file into malloc()-ed C string.
*/