mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
On win32, errno is not the last socket error. Worse, WSAGetLastError() is not the last socket error sometimes (i.e., EWOULDBLOCK). Also, strerror() does not handle winsock errors. Therefore, event_err() and event_warn() are completely wrong for windows socket errors. Fix that.
svn:r936
This commit is contained in:
parent
a710d817ad
commit
de069b9977
@ -123,7 +123,8 @@ Changes in current version:
|
|||||||
o Make event_add not change any state if it fails; reported by Ian Bell.
|
o Make event_add not change any state if it fails; reported by Ian Bell.
|
||||||
o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me.
|
o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me.
|
||||||
o Match the query in DNS replies to the query in the request; from Vsevolod Stakhov.
|
o Match the query in DNS replies to the query in the request; from Vsevolod Stakhov.
|
||||||
|
o Add new utility functions to correctly observe and log winsock errors.
|
||||||
|
|
||||||
Changes in 1.4.0:
|
Changes in 1.4.0:
|
||||||
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
|
||||||
o demote most http warnings to debug messages
|
o demote most http warnings to debug messages
|
||||||
|
34
evdns.c
34
evdns.c
@ -362,21 +362,6 @@ static int strtoint(const char *const str);
|
|||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static int
|
static int
|
||||||
last_error(evutil_socket_t sock)
|
|
||||||
{
|
|
||||||
int optval, optvallen=sizeof(optval);
|
|
||||||
int err = WSAGetLastError();
|
|
||||||
if (err == WSAEWOULDBLOCK && sock >= 0) {
|
|
||||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
|
|
||||||
&optvallen))
|
|
||||||
return err;
|
|
||||||
if (optval)
|
|
||||||
return optval;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
|
|
||||||
}
|
|
||||||
static int
|
|
||||||
error_is_eagain(int err)
|
error_is_eagain(int err)
|
||||||
{
|
{
|
||||||
return err == EAGAIN || err == WSAEWOULDBLOCK;
|
return err == EAGAIN || err == WSAEWOULDBLOCK;
|
||||||
@ -396,7 +381,6 @@ inet_aton(const char *c, struct in_addr *addr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define last_error(sock) (errno)
|
|
||||||
#define error_is_eagain(err) ((err) == EAGAIN)
|
#define error_is_eagain(err) ((err) == EAGAIN)
|
||||||
#endif
|
#endif
|
||||||
#define CLOSE_SOCKET(s) EVUTIL_CLOSESOCKET(s)
|
#define CLOSE_SOCKET(s) EVUTIL_CLOSESOCKET(s)
|
||||||
@ -1183,9 +1167,9 @@ nameserver_read(struct nameserver *ns) {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
const int r = recv(ns->socket, packet, sizeof(packet), 0);
|
const int r = recv(ns->socket, packet, sizeof(packet), 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
int err = last_error(ns->socket);
|
int err = evutil_socket_geterror(ns->socket);
|
||||||
if (error_is_eagain(err)) return;
|
if (error_is_eagain(err)) return;
|
||||||
nameserver_failed(ns, strerror(err));
|
nameserver_failed(ns, evutil_socket_error_to_string(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ns->timedout = 0;
|
ns->timedout = 0;
|
||||||
@ -1207,10 +1191,10 @@ server_port_read(struct evdns_server_port *s) {
|
|||||||
r = recvfrom(s->socket, packet, sizeof(packet), 0,
|
r = recvfrom(s->socket, packet, sizeof(packet), 0,
|
||||||
(struct sockaddr*) &addr, &addrlen);
|
(struct sockaddr*) &addr, &addrlen);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
int err = last_error(s->socket);
|
int err = evutil_socket_geterror(s->socket);
|
||||||
if (error_is_eagain(err)) return;
|
if (error_is_eagain(err)) return;
|
||||||
log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
|
log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
|
||||||
strerror(err), err);
|
evutil_socket_error_to_string(err), err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
|
request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
|
||||||
@ -1226,10 +1210,10 @@ server_port_flush(struct evdns_server_port *port)
|
|||||||
int r = sendto(port->socket, req->response, req->response_len, 0,
|
int r = sendto(port->socket, req->response, req->response_len, 0,
|
||||||
(struct sockaddr*) &req->addr, req->addrlen);
|
(struct sockaddr*) &req->addr, req->addrlen);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
int err = last_error(port->socket);
|
int err = evutil_socket_geterror(port->socket);
|
||||||
if (error_is_eagain(err))
|
if (error_is_eagain(err))
|
||||||
return;
|
return;
|
||||||
log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", strerror(err), err);
|
log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", evutil_socket_error_to_string(err), err);
|
||||||
}
|
}
|
||||||
if (server_request_free(req)) {
|
if (server_request_free(req)) {
|
||||||
/* we released the last reference to req->port. */
|
/* we released the last reference to req->port. */
|
||||||
@ -1758,7 +1742,7 @@ evdns_server_request_respond(struct evdns_server_request *_req, int err)
|
|||||||
r = sendto(port->socket, req->response, req->response_len, 0,
|
r = sendto(port->socket, req->response, req->response_len, 0,
|
||||||
(struct sockaddr*) &req->addr, req->addrlen);
|
(struct sockaddr*) &req->addr, req->addrlen);
|
||||||
if (r<0) {
|
if (r<0) {
|
||||||
int sock_err = last_error(port->socket);
|
int sock_err = evutil_socket_geterror(port->socket);
|
||||||
if (! error_is_eagain(sock_err))
|
if (! error_is_eagain(sock_err))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1936,9 +1920,9 @@ static int
|
|||||||
evdns_request_transmit_to(struct evdns_request *req, struct nameserver *server) {
|
evdns_request_transmit_to(struct evdns_request *req, struct nameserver *server) {
|
||||||
const int r = send(server->socket, req->request, req->request_len, 0);
|
const int r = send(server->socket, req->request, req->request_len, 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
int err = last_error(server->socket);
|
int err = evutil_socket_geterror(server->socket);
|
||||||
if (error_is_eagain(err)) return 1;
|
if (error_is_eagain(err)) return 1;
|
||||||
nameserver_failed(req->ns, strerror(err));
|
nameserver_failed(req->ns, evutil_socket_error_to_string(err));
|
||||||
return 2;
|
return 2;
|
||||||
} else if (r != (int)req->request_len) {
|
} else if (r != (int)req->request_len) {
|
||||||
return 1; /* short write */
|
return 1; /* short write */
|
||||||
|
4
event.c
4
event.c
@ -1487,13 +1487,13 @@ evthread_set_id_callback(struct event_base *base,
|
|||||||
#endif
|
#endif
|
||||||
base->th_get_id = id_fn;
|
base->th_get_id = id_fn;
|
||||||
base->th_owner_id = (*id_fn)();
|
base->th_owner_id = (*id_fn)();
|
||||||
/*
|
/*
|
||||||
* If another thread wants to add a new event, we need to notify
|
* If another thread wants to add a new event, we need to notify
|
||||||
* the thread that owns the base to wakeup for rescheduling.
|
* the thread that owns the base to wakeup for rescheduling.
|
||||||
*/
|
*/
|
||||||
if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0,
|
if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0,
|
||||||
base->th_notify_fd) == -1)
|
base->th_notify_fd) == -1)
|
||||||
event_err(1, "%s: socketpair", __func__);
|
event_sock_err(1, -1, "%s: socketpair", __func__);
|
||||||
|
|
||||||
evutil_make_socket_nonblocking(base->th_notify_fd[0]);
|
evutil_make_socket_nonblocking(base->th_notify_fd[0]);
|
||||||
evutil_make_socket_nonblocking(base->th_notify_fd[1]);
|
evutil_make_socket_nonblocking(base->th_notify_fd[1]);
|
||||||
|
94
evutil.c
94
evutil.c
@ -218,6 +218,100 @@ evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
int
|
||||||
|
evutil_socket_geterror(evutil_socket_t sock)
|
||||||
|
{
|
||||||
|
int optval, optvallen=sizeof(optval);
|
||||||
|
int err = WSAGetLastError();
|
||||||
|
if (err == WSAEWOULDBLOCK && sock >= 0) {
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
|
||||||
|
&optvallen))
|
||||||
|
return err;
|
||||||
|
if (optval)
|
||||||
|
return optval;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define E(code, s) { code, (s " [" #code " ]") }
|
||||||
|
static struct { int code; const char *msg; } windows_socket_errors[] = {
|
||||||
|
E(WSAEINTR, "Interrupted function call"),
|
||||||
|
E(WSAEACCES, "Permission denied"),
|
||||||
|
E(WSAEFAULT, "Bad address"),
|
||||||
|
E(WSAEINVAL, "Invalid argument"),
|
||||||
|
E(WSAEMFILE, "Too many open files"),
|
||||||
|
E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
|
||||||
|
E(WSAEINPROGRESS, "Operation now in progress"),
|
||||||
|
E(WSAEALREADY, "Operation already in progress"),
|
||||||
|
E(WSAENOTSOCK, "Socket operation on nonsocket"),
|
||||||
|
E(WSAEDESTADDRREQ, "Destination address required"),
|
||||||
|
E(WSAEMSGSIZE, "Message too long"),
|
||||||
|
E(WSAEPROTOTYPE, "Protocol wrong for socket"),
|
||||||
|
E(WSAENOPROTOOPT, "Bad protocol option"),
|
||||||
|
E(WSAEPROTONOSUPPORT, "Protocol not supported"),
|
||||||
|
E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
|
||||||
|
/* What's the difference between NOTSUPP and NOSUPPORT? :) */
|
||||||
|
E(WSAEOPNOTSUPP, "Operation not supported"),
|
||||||
|
E(WSAEPFNOSUPPORT, "Protocol family not supported"),
|
||||||
|
E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
|
||||||
|
E(WSAEADDRINUSE, "Address already in use"),
|
||||||
|
E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
|
||||||
|
E(WSAENETDOWN, "Network is down"),
|
||||||
|
E(WSAENETUNREACH, "Network is unreachable"),
|
||||||
|
E(WSAENETRESET, "Network dropped connection on reset"),
|
||||||
|
E(WSAECONNABORTED, "Software caused connection abort"),
|
||||||
|
E(WSAECONNRESET, "Connection reset by peer"),
|
||||||
|
E(WSAENOBUFS, "No buffer space available"),
|
||||||
|
E(WSAEISCONN, "Socket is already connected"),
|
||||||
|
E(WSAENOTCONN, "Socket is not connected"),
|
||||||
|
E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
|
||||||
|
E(WSAETIMEDOUT, "Connection timed out"),
|
||||||
|
E(WSAECONNREFUSED, "Connection refused"),
|
||||||
|
E(WSAEHOSTDOWN, "Host is down"),
|
||||||
|
E(WSAEHOSTUNREACH, "No route to host"),
|
||||||
|
E(WSAEPROCLIM, "Too many processes"),
|
||||||
|
|
||||||
|
/* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
|
||||||
|
E(WSASYSNOTREADY, "Network subsystem is unavailable"),
|
||||||
|
E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
|
||||||
|
E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
|
||||||
|
E(WSAEDISCON, "Graceful shutdown now in progress"),
|
||||||
|
#ifdef WSATYPE_NOT_FOUND
|
||||||
|
E(WSATYPE_NOT_FOUND, "Class type not found"),
|
||||||
|
#endif
|
||||||
|
E(WSAHOST_NOT_FOUND, "Host not found"),
|
||||||
|
E(WSATRY_AGAIN, "Nonauthoritative host not found"),
|
||||||
|
E(WSANO_RECOVERY, "This is a nonrecoverable error"),
|
||||||
|
E(WSANO_DATA, "Valid name, no data record of requested type)"),
|
||||||
|
|
||||||
|
/* There are some more error codes whose numeric values are marked
|
||||||
|
* <b>OS dependent</b>. They start with WSA_, apparently for the same
|
||||||
|
* reason that practitioners of some craft traditions deliberately
|
||||||
|
* introduce imperfections into their baskets and rugs "to allow the
|
||||||
|
* evil spirits to escape." If we catch them, then our binaries
|
||||||
|
* might not report consistent results across versions of Windows.
|
||||||
|
* Thus, I'm going to let them all fall through.
|
||||||
|
*/
|
||||||
|
{ -1, NULL },
|
||||||
|
};
|
||||||
|
#undef E
|
||||||
|
/** Equivalent to strerror, but for windows socket errors. */
|
||||||
|
const char *
|
||||||
|
evutil_socket_error_to_string(int errcode)
|
||||||
|
{
|
||||||
|
/* XXXX Is there really no built-in function to do this? */
|
||||||
|
int i;
|
||||||
|
for (i=0; windows_socket_errors[i].code >= 0; ++i) {
|
||||||
|
if (e == windows_socket_errors[i].code)
|
||||||
|
return windows_socket_errors[i].msg;
|
||||||
|
}
|
||||||
|
return strerror(e);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
|
evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
|
||||||
{
|
{
|
||||||
|
14
http.c
14
http.c
@ -1141,7 +1141,7 @@ evhttp_connection_cb(struct bufferevent *bufev, void *arg)
|
|||||||
struct evhttp_connection *evcon = arg;
|
struct evhttp_connection *evcon = arg;
|
||||||
int error;
|
int error;
|
||||||
socklen_t errsz = sizeof(error);
|
socklen_t errsz = sizeof(error);
|
||||||
|
|
||||||
/* Check if the connection completed */
|
/* Check if the connection completed */
|
||||||
if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
|
if (getsockopt(evcon->fd, SOL_SOCKET, SO_ERROR, (void*)&error,
|
||||||
&errsz) == -1) {
|
&errsz) == -1) {
|
||||||
@ -1153,7 +1153,7 @@ evhttp_connection_cb(struct bufferevent *bufev, void *arg)
|
|||||||
if (error) {
|
if (error) {
|
||||||
event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
|
event_debug(("%s: connect failed for \"%s:%d\" on %d: %s",
|
||||||
__func__, evcon->address, evcon->port, evcon->fd,
|
__func__, evcon->address, evcon->port, evcon->fd,
|
||||||
strerror(error)));
|
evutil_socket_error_to_string(error)));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1770,7 +1770,7 @@ evhttp_connection_connect(struct evhttp_connection *evcon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
|
if (socket_connect(evcon->fd, evcon->address, evcon->port) == -1) {
|
||||||
event_warn("%s: connection to \"%s\" failed",
|
event_sock_warn(evcon->fd, "%s: connection to \"%s\" failed",
|
||||||
__func__, evcon->address);
|
__func__, evcon->address);
|
||||||
EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
|
EVUTIL_CLOSESOCKET(evcon->fd); evcon->fd = -1;
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -2340,7 +2340,7 @@ evhttp_bind_socket(struct evhttp *http, const char *address, ev_uint16_t port)
|
|||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
if (listen(fd, 128) == -1) {
|
if (listen(fd, 128) == -1) {
|
||||||
event_warn("%s: listen", __func__);
|
event_sock_warn(fd, "%s: listen", __func__);
|
||||||
EVUTIL_CLOSESOCKET(fd);
|
EVUTIL_CLOSESOCKET(fd);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
@ -2763,7 +2763,7 @@ evhttp_get_request(struct evhttp *http, evutil_socket_t fd,
|
|||||||
|
|
||||||
evcon = evhttp_get_request_connection(http, fd, sa, salen);
|
evcon = evhttp_get_request_connection(http, fd, sa, salen);
|
||||||
if (evcon == NULL) {
|
if (evcon == NULL) {
|
||||||
event_warn("%s: cannot get connection on %d", __func__, fd);
|
event_sock_warn(fd, "%s: cannot get connection on %d", __func__, fd);
|
||||||
EVUTIL_CLOSESOCKET(fd);
|
EVUTIL_CLOSESOCKET(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2860,8 +2860,8 @@ bind_socket_ai(struct addrinfo *ai, int reuse)
|
|||||||
/* Create listen socket */
|
/* Create listen socket */
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
event_warn("socket");
|
event_sock_warn(-1, "socket");
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evutil_make_socket_nonblocking(fd) < 0)
|
if (evutil_make_socket_nonblocking(fd) < 0)
|
||||||
|
@ -117,14 +117,28 @@ int evutil_make_socket_nonblocking(evutil_socket_t sock);
|
|||||||
#define EVUTIL_CLOSESOCKET(s) close(s)
|
#define EVUTIL_CLOSESOCKET(s) close(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Winsock handles socket errors differently from the rest of the world.
|
||||||
|
* Elsewhere, a socket error is like any other error and is stored in errno.
|
||||||
|
* But winsock functions require you to retrieve the error with a special
|
||||||
|
* function, and don't let you use strerror for the error codes. And handling
|
||||||
|
* EWOULD block is ... different. */
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
/** Return the most recent socket error. Not idempotent. */
|
||||||
#define EVUTIL_SOCKET_ERROR() WSAGetLastError()
|
#define EVUTIL_SOCKET_ERROR() WSAGetLastError()
|
||||||
|
/** Replace the most recent socket error with errcode */
|
||||||
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
|
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
|
||||||
do { WSASetLastError(errcode); } while (0)
|
do { WSASetLastError(errcode); } while (0)
|
||||||
|
/** Return the most recent socket error to occur on sock. */
|
||||||
|
int evutil_socket_geterror(evutil_socket_t sock);
|
||||||
|
/** Convert a socket error to a string. */
|
||||||
|
const char *evutil_socket_error_to_string(int errcode);
|
||||||
#else
|
#else
|
||||||
#define EVUTIL_SOCKET_ERROR() (errno)
|
#define EVUTIL_SOCKET_ERROR() (errno)
|
||||||
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
|
#define EVUTIL_SET_SOCKET_ERROR(errcode) \
|
||||||
do { errno = (errcode); } while (0)
|
do { errno = (errcode); } while (0)
|
||||||
|
#define evutil_socket_geterror(sock) (errno)
|
||||||
|
#define evutil_socket_error_to_string(errcode) (strerror(errcode))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
44
log.c
44
log.c
@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static void _warn_helper(int severity, int log_errno, const char *fmt,
|
static void _warn_helper(int severity, const char *errstr, const char *fmt,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
static void event_log(int severity, const char *msg);
|
static void event_log(int severity, const char *msg);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ event_err(int eval, const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_ERR, errno, fmt, ap);
|
_warn_helper(_EVENT_LOG_ERR, strerror(errno), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
@ -83,7 +83,30 @@ event_warn(const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_WARN, errno, fmt, ap);
|
_warn_helper(_EVENT_LOG_WARN, strerror(errno), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
event_sock_err(int eval, evutil_socket_t sock, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int err = evutil_socket_geterror(sock);
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
_warn_helper(_EVENT_LOG_ERR, evutil_socket_error_to_string(err), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
exit(eval);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
event_sock_warn(int sock, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int err = evutil_socket_geterror(sock);
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
_warn_helper(_EVENT_LOG_WARN, evutil_socket_error_to_string(err), fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +116,7 @@ event_errx(int eval, const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_ERR, -1, fmt, ap);
|
_warn_helper(_EVENT_LOG_ERR, NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
exit(eval);
|
exit(eval);
|
||||||
}
|
}
|
||||||
@ -104,7 +127,7 @@ event_warnx(const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_WARN, -1, fmt, ap);
|
_warn_helper(_EVENT_LOG_WARN, NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +137,7 @@ event_msgx(const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_MSG, -1, fmt, ap);
|
_warn_helper(_EVENT_LOG_MSG, NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,12 +147,12 @@ _event_debugx(const char *fmt, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
_warn_helper(_EVENT_LOG_DEBUG, -1, fmt, ap);
|
_warn_helper(_EVENT_LOG_DEBUG, NULL, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_warn_helper(int severity, int log_errno, const char *fmt, va_list ap)
|
_warn_helper(int severity, const char *errstr, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -139,11 +162,10 @@ _warn_helper(int severity, int log_errno, const char *fmt, va_list ap)
|
|||||||
else
|
else
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
if (log_errno >= 0) {
|
if (errstr) {
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
if (len < sizeof(buf) - 3) {
|
if (len < sizeof(buf) - 3) {
|
||||||
evutil_snprintf(buf + len, sizeof(buf) - len, ": %s",
|
evutil_snprintf(buf + len, sizeof(buf) - len, ": %s", errstr);
|
||||||
strerror(log_errno));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
log.h
2
log.h
@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
void event_err(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
||||||
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
void event_warn(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||||
|
void event_sock_err(int eval, int sock, const char *fmt, ...) EV_CHECK_FMT(3,4);
|
||||||
|
void event_sock_warn(int sock, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
||||||
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
void event_errx(int eval, const char *fmt, ...) EV_CHECK_FMT(2,3);
|
||||||
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||||
void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
void event_msgx(const char *fmt, ...) EV_CHECK_FMT(1,2);
|
||||||
|
10
signal.c
10
signal.c
@ -82,7 +82,7 @@ evsignal_cb(evutil_socket_t fd, short what, void *arg)
|
|||||||
|
|
||||||
n = recv(fd, signals, sizeof(signals), 0);
|
n = recv(fd, signals, sizeof(signals), 0);
|
||||||
if (n == -1)
|
if (n == -1)
|
||||||
event_err(1, "%s: read", __func__);
|
event_sock_err(1, fd, "%s: read", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SETFD
|
#ifdef HAVE_SETFD
|
||||||
@ -106,7 +106,7 @@ evsignal_init(struct event_base *base)
|
|||||||
*/
|
*/
|
||||||
if (evutil_socketpair(
|
if (evutil_socketpair(
|
||||||
AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||||
event_err(1, "%s: socketpair", __func__);
|
event_sock_err(1, -1, "%s: socketpair", __func__);
|
||||||
|
|
||||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
||||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
|
FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
|
||||||
@ -278,6 +278,9 @@ static void
|
|||||||
evsignal_handler(int sig)
|
evsignal_handler(int sig)
|
||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
#ifdef WIN32
|
||||||
|
int socket_errno = EVUTIL_SOCKET_ERROR();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (evsignal_base == NULL) {
|
if (evsignal_base == NULL) {
|
||||||
event_warn(
|
event_warn(
|
||||||
@ -296,6 +299,9 @@ evsignal_handler(int sig)
|
|||||||
/* Wake up our notification mechanism */
|
/* Wake up our notification mechanism */
|
||||||
send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0);
|
send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0);
|
||||||
errno = save_errno;
|
errno = save_errno;
|
||||||
|
#ifdef WIN32
|
||||||
|
EVUTIL_SET_SOCKET_ERRNO(socket_error);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user