Hi Freddie, Lewis,
On 02/10/2015 10:54 AM, [email protected] wrote:
> I was referring to the epicsSocketDestroy() in makeSocket() rather
> than the one in verify(). I've checked on a windows machine and I can
> reproduce Lewis' behaviour - if I add a print of SOCKERRNO after a
> failed bind() in makeSocket() I see an error code of 10048, but
> printing it out again after the call to epicsSocketDestroy () in
> makeSocket() gives 0
My apologies, you were of course correct in what's happening, I should
have read your original message more closely.
>> On Feb 10, 2015, at 4:29 AM, [email protected] wrote:
>>
>>> I think the bind() in makeSocket() is failing (as expected) but
>>> the
>> subsequent successful call to epicsSocketDestroy() in the same
>> function is clearing the error code, hence when the check is made
>> in repeaterClient::verify () rather than SOCK_EADDRINUSE it is
>> finding 0. One way to fix it might be to change makeSocket() to
>> make a copy of any socket error code and then return that (or 0 on
>> success) rather than true/false
I have implemented this change in the attached patch. Unfortunately the
libCom osiSock.h interface didn't provide a way to convert an arbitrary
socket error number into a string, so I also had to extend the API to
add that functionality. Luckily there are only 2 implementations since
Windows is the only OS that doesn't use errno and strerror() for this.
This patch will not fix the original cause of Lewis' error from the
repeater, but it will at least result in the correct message being
displayed for it. If one of you could test this patch on Windows I will
commit the changes and publish it on the Known Problems page.
- Andrew
--
Doctorow's Law: Anytime someone puts a lock on something you own,
against your wishes, and doesn't give you the key, they're
not doing it for your benefit.
=== modified file 'src/ca/repeater.cpp'
--- src/ca/repeater.cpp 2013-05-16 18:33:31 +0000
+++ src/ca/repeater.cpp 2015-02-10 20:12:45 +0000
@@ -108,7 +108,7 @@
/*
* makeSocket()
*/
-static bool makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock )
+static int makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock )
{
int status;
union {
@@ -118,7 +118,7 @@
SOCKET sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, 0 );
if ( sock == INVALID_SOCKET ) {
- return false;
+ return SOCKERRNO;
}
/*
@@ -132,15 +132,16 @@
bd.ia.sin_port = htons ( port );
status = bind ( sock, &bd.sa, (int) sizeof(bd) );
if ( status < 0 ) {
+ status = SOCKERRNO;
epicsSocketDestroy ( sock );
- return false;
+ return status;
}
if ( reuseAddr ) {
epicsSocketEnableAddressReuseDuringTimeWaitState ( sock );
}
}
*pSock = sock;
- return true;
+ return 0;
}
repeaterClient::repeaterClient ( const osiSockAddr &fromIn ) :
@@ -156,10 +157,10 @@
{
int status;
- if ( ! makeSocket ( PORT_ANY, false, & this->sock ) ) {
+ if ( int sockerrno = makeSocket ( PORT_ANY, false, & this->sock ) ) {
char sockErrBuf[64];
- epicsSocketConvertErrnoToString (
- sockErrBuf, sizeof ( sockErrBuf ) );
+ epicsSocketConvertErrorToString (
+ sockErrBuf, sizeof ( sockErrBuf ), sockerrno );
fprintf ( stderr, "%s: no client sock because \"%s\"\n",
__FILE__, sockErrBuf );
return false;
@@ -300,20 +301,20 @@
bool repeaterClient::verify ()
{
SOCKET tmpSock;
- bool success = makeSocket ( this->port (), false, & tmpSock );
- if ( success ) {
+ int sockerrno = makeSocket ( this->port (), false, & tmpSock );
+ if ( sockerrno == 0 ) {
epicsSocketDestroy ( tmpSock );
}
else {
- if ( SOCKERRNO != SOCK_EADDRINUSE ) {
+ if ( sockerrno != SOCK_EADDRINUSE ) {
char sockErrBuf[64];
- epicsSocketConvertErrnoToString (
- sockErrBuf, sizeof ( sockErrBuf ) );
+ epicsSocketConvertErrorToString (
+ sockErrBuf, sizeof ( sockErrBuf ), sockerrno );
fprintf ( stderr, "CA Repeater: bind test err was \"%s\"\n",
sockErrBuf );
}
}
- return ! success;
+ return !!sockerrno; /* No socket errors => verification failed */
}
@@ -387,10 +388,10 @@
if ( ! init ) {
SOCKET sock;
- if ( ! makeSocket ( PORT_ANY, true, & sock ) ) {
+ if ( int sockerrno = makeSocket ( PORT_ANY, true, & sock ) ) {
char sockErrBuf[64];
- epicsSocketConvertErrnoToString (
- sockErrBuf, sizeof ( sockErrBuf ) );
+ epicsSocketConvertErrorToString (
+ sockErrBuf, sizeof ( sockErrBuf ), sockerrno );
fprintf ( stderr, "%s: Unable to create repeater bind test socket because \"%s\"\n",
__FILE__, sockErrBuf );
}
@@ -511,18 +512,18 @@
port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT,
static_cast <unsigned short> (CA_REPEATER_PORT) );
- if ( ! makeSocket ( port, true, & sock ) ) {
+ if ( int sockerrno = makeSocket ( port, true, & sock ) ) {
/*
* test for server was already started
*/
- if ( SOCKERRNO == SOCK_EADDRINUSE ) {
+ if ( sockerrno == SOCK_EADDRINUSE ) {
osiSockRelease ();
debugPrintf ( ( "CA Repeater: exiting because a repeater is already running\n" ) );
return;
}
char sockErrBuf[64];
- epicsSocketConvertErrnoToString (
- sockErrBuf, sizeof ( sockErrBuf ) );
+ epicsSocketConvertErrorToString (
+ sockErrBuf, sizeof ( sockErrBuf ), sockerrno );
fprintf ( stderr, "%s: Unable to create repeater socket because \"%s\" - fatal\n",
__FILE__, sockErrBuf );
osiSockRelease ();
=== modified file 'src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp'
--- src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp 2010-10-05 19:27:37 +0000
+++ src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp 2015-02-10 20:18:16 +0000
@@ -20,16 +20,15 @@
#include "epicsStdio.h"
/*
- * epicsSocketConvertErrnoToString ()
+ * epicsSocketConvertErrorToString ()
*/
-void epicsSocketConvertErrnoToString (
- char * pBuf, unsigned bufSize )
+void epicsSocketConvertErrorToString (
+ char * pBuf, unsigned bufSize, int theSockError )
{
if ( bufSize ) {
/*
* this does not work on systems prior to W2K
*/
- int theSockError = SOCKERRNO;
DWORD success = FormatMessage (
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, theSockError,
@@ -45,3 +44,12 @@
}
}
}
+
+/*
+ * epicsSocketConvertErrnoToString ()
+ */
+void epicsSocketConvertErrnoToString (
+ char * pBuf, unsigned bufSize )
+{
+ epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO );
+}
=== modified file 'src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp'
--- src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp 2010-10-05 19:27:37 +0000
+++ src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp 2015-02-10 20:17:50 +0000
@@ -22,14 +22,22 @@
#include "osiSock.h"
/*
- * epicsSocketConvertErrnoToString()
+ * epicsSocketConvertErrorToString()
*/
-void epicsSocketConvertErrnoToString (
- char * pBuf, unsigned bufSize )
+void epicsSocketConvertErrorToString (
+ char * pBuf, unsigned bufSize, int theSockError )
{
if ( bufSize ) {
- strncpy ( pBuf, strerror ( SOCKERRNO ), bufSize );
+ strncpy ( pBuf, strerror ( theSockError ), bufSize );
pBuf[bufSize-1] = '\0';
}
}
+/*
+ * epicsSocketConvertErrnoToString()
+ */
+void epicsSocketConvertErrnoToString (
+ char * pBuf, unsigned bufSize )
+{
+ epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO );
+}
=== modified file 'src/libCom/osi/osiSock.h'
--- src/libCom/osi/osiSock.h 2010-10-05 19:27:37 +0000
+++ src/libCom/osi/osiSock.h 2015-02-10 20:16:41 +0000
@@ -140,9 +140,11 @@
epicsShareFunc void epicsShareAPI osiSockRelease (void);
/*
- * convert socket error number to a string
+ * convert socket error numbers to a string
*/
-epicsShareFunc void epicsSocketConvertErrnoToString (
+epicsShareFunc void epicsSocketConvertErrorToString (
+ char * pBuf, unsigned bufSize, int error );
+epicsShareFunc void epicsSocketConvertErrnoToString (
char * pBuf, unsigned bufSize );
typedef union osiSockAddr {
- Replies:
- Re: CA Repeater: bind test err was "The operation completed successfully. " J. Lewis Muir
- References:
- CA Repeater: bind test err was "The operation completed successfully. " J. Lewis Muir
- RE: CA Repeater: bind test err was "The operation completed successfully. " freddie.akeroyd
- Re: CA Repeater: bind test err was "The operation completed successfully. " Johnson, Andrew N.
- RE: CA Repeater: bind test err was "The operation completed successfully. " freddie.akeroyd
- Navigate by Date:
- Prev:
Re: medm3.1.8 linker problem Ralph Lange
- Next:
Re: CA Repeater: bind test err was "The operation completed successfully. " J. Lewis Muir
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
<2015>
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: CA Repeater: bind test err was "The operation completed successfully. " freddie.akeroyd
- Next:
Re: CA Repeater: bind test err was "The operation completed successfully. " J. Lewis Muir
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
<2015>
2016
2017
2018
2019
2020
2021
2022
2023
2024
|