From 02aa7e2f73293ada08705523ce4d393bda25c249 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 10 Feb 2015 18:10:33 -0600 Subject: [PATCH] Stop bogus error messages from CA Repeater on Windows Required adding a new API to osiSock.h and the 2 implementations of epicsSocketConvertErrnoToString. --- src/ca/repeater.cpp | 85 ++++++++----------- .../WIN32/epicsSocketConvertErrnoToString.cpp | 40 +++++---- .../epicsSocketConvertErrnoToString.cpp | 20 +++-- src/libCom/osi/osiSock.h | 6 +- 4 files changed, 75 insertions(+), 76 deletions(-) diff --git a/src/ca/repeater.cpp b/src/ca/repeater.cpp index ef271e461..847431d34 100644 --- a/src/ca/repeater.cpp +++ b/src/ca/repeater.cpp @@ -3,8 +3,7 @@ * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* @@ -16,26 +15,6 @@ * Author: Jeff Hill * Date: 3-27-90 * - * Control System Software for the GTA Project - * - * Copyright 1988, 1989, the Regents of the University of California. - * - * This software was produced under a U.S. Government contract - * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is - * operated by the University of California for the U.S. Department - * of Energy. - * - * Developed by the Controls and Automation Group (AT-8) - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Direct inqueries to: - * Jeff HIll, AT-8, Mail Stop H820 - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * Phone: (505) 665-1831 - * E-mail: johill@lanl.gov - * * PURPOSE: * Broadcasts fan out over the LAN, but old IP kernels do not allow * two processes on the same machine to get the same broadcast @@ -108,17 +87,17 @@ static const unsigned short PORT_ANY = 0u; /* * makeSocket() */ -static bool makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock ) +static int makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock ) { int status; - union { - struct sockaddr_in ia; - struct sockaddr sa; - } bd; + union { + struct sockaddr_in ia; + struct sockaddr sa; + } bd; SOCKET sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, 0 ); if ( sock == INVALID_SOCKET ) { - return false; + return SOCKERRNO; } /* @@ -132,15 +111,16 @@ static bool makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock ) 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 +136,10 @@ bool repeaterClient::connect () { 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 +280,25 @@ inline bool repeaterClient::identicalPort ( const osiSockAddr &fromIn ) bool repeaterClient::verify () { SOCKET tmpSock; - bool success = makeSocket ( this->port (), false, & tmpSock ); - if ( success ) { + int sockerrno = makeSocket ( this->port (), false, & tmpSock ); + + if ( sockerrno == SOCK_EADDRINUSE ) { + // Normal result, client using port + return true; + } + + if ( sockerrno == 0 ) { + // Client went away, released port epicsSocketDestroy ( tmpSock ); } else { - if ( SOCKERRNO != SOCK_EADDRINUSE ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "CA Repeater: bind test err was \"%s\"\n", - sockErrBuf ); - } + char sockErrBuf[64]; + epicsSocketConvertErrorToString ( + sockErrBuf, sizeof ( sockErrBuf ), sockerrno ); + fprintf ( stderr, "CA Repeater: Bind test error \"%s\"\n", + sockErrBuf ); } - return ! success; + return false; } @@ -387,10 +372,10 @@ static void register_new_client ( osiSockAddr & from, 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 +496,18 @@ void ca_repeater () port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT, static_cast (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 (); diff --git a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp index d0a70aeaa..5ab809cde 100644 --- a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp +++ b/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp @@ -1,11 +1,9 @@ - /*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ @@ -20,28 +18,36 @@ #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, - MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ), /* Default language */ - pBuf, bufSize, NULL ); - if ( ! success ) { + /* + * this does not work on systems prior to W2K + */ + DWORD success = FormatMessage ( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, theSockError, + MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ), /* Default language */ + pBuf, bufSize, NULL ); + if ( ! success ) { int status = epicsSnprintf ( pBuf, bufSize, "WINSOCK Error %d", theSockError ); if ( status <= 0 ) { strncpy ( pBuf, "WINSOCK Error", bufSize ); pBuf [bufSize - 0] = '\0'; } - } + } } } + +/* + * epicsSocketConvertErrnoToString () + */ +void epicsSocketConvertErrnoToString ( + char * pBuf, unsigned bufSize ) +{ + epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO ); +} diff --git a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp index 0edee89de..0e0ef94f0 100644 --- a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp +++ b/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp @@ -1,11 +1,9 @@ - /*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found +* EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /* osdSock.c */ @@ -22,14 +20,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 ); +} diff --git a/src/libCom/osi/osiSock.h b/src/libCom/osi/osiSock.h index b098290da..1b52c7993 100644 --- a/src/libCom/osi/osiSock.h +++ b/src/libCom/osi/osiSock.h @@ -140,9 +140,11 @@ epicsShareFunc int epicsShareAPI osiSockAttach (void); /* returns T if success, 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 {