Commit 0da49d8b authored by rswindell's avatar rswindell
Browse files

socket_strerror() is now thread-safe.

parent 449360d1
......@@ -75,6 +75,7 @@ BOOL DLLCALL js_argc(JSContext *cx, uintN argc, uintN min)
static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
jsval idval;
char err[128];
jsint tiny;
JSString* js_str;
......@@ -86,7 +87,7 @@ static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
*vp=DOUBLE_TO_JSVAL(ERROR_VALUE);
break;
case GLOB_PROP_SOCKET_ERRNO_STR:
if((js_str=JS_NewStringCopyZ(cx, socket_strerror(socket_errno)))==NULL)
if((js_str=JS_NewStringCopyZ(cx, socket_strerror(socket_errno, err, sizeof(err))))==NULL)
return(JS_FALSE);
*vp = STRING_TO_JSVAL(js_str);
break;
......
......@@ -254,6 +254,7 @@ static SOCKET open_socket(int family, int type, service_t* serv)
static int close_socket(SOCKET sock)
{
char err[128];
int result;
if(sock==INVALID_SOCKET)
......@@ -264,7 +265,7 @@ static int close_socket(SOCKET sock)
if(startup!=NULL && startup->socket_open!=NULL)
startup->socket_open(startup->cbdata,FALSE);
if(result!=0)
lprintf(LOG_WARNING,"%04d !ERROR %d (%s) closing socket",sock, ERROR_VALUE, socket_strerror(socket_errno));
lprintf(LOG_WARNING,"%04d !ERROR %d (%s) closing socket",sock, ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)));
return(result);
}
......@@ -1649,8 +1650,9 @@ static void cleanup(int code)
#ifdef _WINSOCKAPI_
if(WSAInitialized) {
char err[128];
if(WSACleanup()!=0)
lprintf(LOG_ERR,"0000 !WSACleanup ERROR %d (%s)",ERROR_VALUE, socket_strerror(socket_errno));
lprintf(LOG_ERR,"0000 !WSACleanup ERROR %d (%s)",ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)));
WSAInitialized = FALSE;
}
#endif
......@@ -1689,7 +1691,8 @@ const char* DLLCALL services_ver(void)
void service_udp_sock_cb(SOCKET sock, void *cbdata)
{
service_t *serv = (service_t *)cbdata;
int optval;
int optval;
char err[128];
open_socket_cb(sock, cbdata);
......@@ -1697,14 +1700,14 @@ void service_udp_sock_cb(SOCKET sock, void *cbdata)
optval=TRUE;
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval,sizeof(optval))!=0) {
lprintf(LOG_ERR,"%04d !ERROR %d (%s) setting %s socket option"
,sock, ERROR_VALUE, socket_strerror(socket_errno), serv->protocol);
,sock, ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)), serv->protocol);
close_socket(sock);
return;
}
#ifdef BSD
if(setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char*)&optval,sizeof(optval))!=0) {
lprintf(LOG_ERR,"%04d !ERROR %d (%s) setting %s socket option"
,sock, ERROR_VALUE, socket_strerror(socket_errno), serv->protocol);
,sock, ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)), serv->protocol);
close_socket(sock);
return;
}
......@@ -2006,7 +2009,7 @@ void DLLCALL services_thread(void* arg)
else if(ERROR_VALUE == ENOTSOCK)
lprintf(LOG_NOTICE,"0000 Services sockets closed");
else
lprintf(LOG_WARNING,"0000 !ERROR %d (%s) selecting sockets",ERROR_VALUE, socket_strerror(socket_errno));
lprintf(LOG_WARNING,"0000 !ERROR %d (%s) selecting sockets",ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
continue;
}
......@@ -2038,7 +2041,7 @@ void DLLCALL services_thread(void* arg)
if(udp_len<1) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_WARNING,"%04d %s !ERROR %d (%s) recvfrom failed"
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
continue;
}
......@@ -2046,7 +2049,7 @@ void DLLCALL services_thread(void* arg)
==INVALID_SOCKET) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_ERR,"%04d %s !ERROR %d (%s) opening socket"
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
continue;
}
......@@ -2059,7 +2062,7 @@ void DLLCALL services_thread(void* arg)
,(char*)&optval,sizeof(optval))!=0) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_ERR,"%04d %s !ERROR %d (%s) setting socket option"
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
close_socket(client_socket);
continue;
}
......@@ -2068,7 +2071,7 @@ void DLLCALL services_thread(void* arg)
,(char*)&optval,sizeof(optval))!=0) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_ERR,"%04d %s !ERROR %d (%s) setting socket option"
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
close_socket(client_socket);
continue;
}
......@@ -2081,14 +2084,14 @@ void DLLCALL services_thread(void* arg)
/* Failed to re-bind to same port number, use user port */
lprintf(LOG_NOTICE,"%04d %s ERROR %d (%s) re-binding socket to port %u failed, "
"using user port"
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno), service[i].port);
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)), service[i].port);
inet_setaddrport(&addr, 0);
result=bind(client_socket, (struct sockaddr *) &addr, addr_len);
}
if(result!=0) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_ERR,"%04d %s !ERROR %d (%s) re-binding socket to port %u"
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno), service[i].port);
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)), service[i].port);
close_socket(client_socket);
continue;
}
......@@ -2098,7 +2101,7 @@ void DLLCALL services_thread(void* arg)
,(struct sockaddr *)&client_addr, client_addr_len)!=0) {
FREE_AND_NULL(udp_buf);
lprintf(LOG_ERR,"%04d %s !ERROR %d (%s) connect failed"
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,client_socket, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
close_socket(client_socket);
continue;
}
......@@ -2112,7 +2115,7 @@ void DLLCALL services_thread(void* arg)
,service[i].set->socks[j].sock, service[i].protocol);
else
lprintf(LOG_WARNING,"%04d %s !ERROR %d (%s) accepting connection"
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno));
,service[i].set->socks[j].sock, service[i].protocol, ERROR_VALUE, socket_strerror(socket_errno,error,sizeof(error)));
#ifdef _WIN32
if(WSAGetLastError()==WSAENOBUFS) /* recycle (re-init WinSock) on this error */
break;
......
......@@ -1518,6 +1518,7 @@ int iniGetSocketOptions(str_list_t list, const char* section, SOCKET sock
int i;
int result;
char* name;
char err[128];
BYTE* vp;
socklen_t len;
int option;
......@@ -1532,13 +1533,13 @@ int iniGetSocketOptions(str_list_t list, const char* section, SOCKET sock
len=sizeof(type);
if((result=getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&type, &len)) != 0) {
safe_snprintf(error,errlen,"%d (%s) getting socket type", ERROR_VALUE, socket_strerror(socket_errno));
safe_snprintf(error,errlen,"%d (%s) getting socket type", ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)));
return(result);
}
#ifdef IPPROTO_IPV6
len=sizeof(addr);
if((result=getsockname(sock, &addr.addr, &len)) != 0) {
safe_snprintf(error,errlen,"%d (%s) getting socket name", ERROR_VALUE, socket_strerror(socket_errno));
safe_snprintf(error,errlen,"%d (%s) getting socket name", ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)));
return(result);
}
#endif
......@@ -1574,7 +1575,7 @@ int iniGetSocketOptions(str_list_t list, const char* section, SOCKET sock
if((result=setsockopt(sock,level,option,(const char *)vp,len)) != 0) {
safe_snprintf(error,errlen,"%d (%s) setting socket option (%s, %d) to %d"
,ERROR_VALUE, socket_strerror(socket_errno), name, option, value);
,ERROR_VALUE, socket_strerror(socket_errno,err,sizeof(err)), name, option, value);
return(result);
}
}
......
......@@ -58,6 +58,7 @@ BOOL DLLCALL xpms_add(struct xpms_set *xpms_set, int domain, int type,
unsigned int added = 0;
int ret;
char port_str[6];
char err[128];
#ifndef _WIN32
struct addrinfo dummy;
......@@ -154,7 +155,7 @@ BOOL DLLCALL xpms_add(struct xpms_set *xpms_set, int domain, int type,
if(xpms_set->lprintf)
xpms_set->lprintf(LOG_WARNING, "%04d !%s ERROR %d (%s) listening on port %d"
,xpms_set->socks[xpms_set->sock_count].sock, prot, ERROR_VALUE
,socket_strerror(socket_errno), port);
,socket_strerror(socket_errno,err,sizeof(err)), port);
closesocket(xpms_set->socks[xpms_set->sock_count].sock);
FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].address);
FREE_AND_NULL(xpms_set->socks[xpms_set->sock_count].prot);
......
......@@ -352,6 +352,7 @@ int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen
,int (*lprintf)(int level, const char *fmt, ...))
{
char port_str[128];
char err[128];
int result=-1;
uint i;
......@@ -364,7 +365,7 @@ int retry_bind(SOCKET s, const struct sockaddr *addr, socklen_t addrlen
break;
if(lprintf!=NULL)
lprintf(i<retries ? LOG_WARNING:LOG_CRIT
,"%04d !ERROR %d (%s) binding %s socket%s", s, ERROR_VALUE, socket_strerror(socket_errno), prot, port_str);
,"%04d !ERROR %d (%s) binding %s socket%s", s, ERROR_VALUE, socket_strerror(socket_errno, err, sizeof(err)), prot, port_str);
if(i<retries) {
if(lprintf!=NULL)
lprintf(LOG_WARNING,"%04d Will retry in %u seconds (%u of %u)"
......@@ -500,20 +501,21 @@ BOOL inet_addrmatch(union xp_sockaddr* addr1, union xp_sockaddr* addr2)
return FALSE;
}
#if defined(_WINSOCKAPI_)
/* Return the current socket error description (for Windows), like strerror() does for errno */
DLLEXPORT const char* socket_strerror(int error_number)
DLLEXPORT char* socket_strerror(int error_number, char* buf, size_t buflen)
{
static char msg[256];
#if defined(_WINSOCKAPI_)
strlcpy(buf, "Unknown error", buflen);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, // dwFlags
NULL, // lpSource
error_number, // dwMessageId
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
msg,
sizeof(msg),
buf,
buflen,
NULL);
truncsp(msg);
return msg;
}
truncsp(buf);
return buf;
#else
return safe_strerror(error_number, buf, buflen);
#endif
}
......@@ -186,7 +186,7 @@ typedef uint32_t in_addr_t;
static int wsa_error;
#define ERROR_VALUE ((wsa_error=WSAGetLastError())>0 ? wsa_error-WSABASEERR : wsa_error)
#define socket_errno WSAGetLastError()
#define socket_errno WSAGetLastError()
#define sendsocket(s,b,l) send(s,b,l,0)
/* For getaddrinfo() */
......@@ -212,7 +212,6 @@ static int wsa_error;
#define ioctlsocket ioctl
#define ERROR_VALUE errno
#define socket_errno errno
#define socket_strerror strerror
#define sendsocket write /* FreeBSD send() is broken */
#ifdef __WATCOMC__
......@@ -240,10 +239,7 @@ DLLEXPORT const char* inet_addrtop(union xp_sockaddr *addr, char *dest, size_t s
DLLEXPORT uint16_t inet_addrport(union xp_sockaddr *addr);
DLLEXPORT void inet_setaddrport(union xp_sockaddr *addr, uint16_t port);
DLLEXPORT BOOL inet_addrmatch(union xp_sockaddr* addr1, union xp_sockaddr* addr2);
#if defined(_WINSOCKAPI_)
DLLEXPORT const char* socket_strerror(int);
#endif
DLLEXPORT char* socket_strerror(int, char*, size_t);
#ifdef __cplusplus
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment