From 1a094f5971c7649cb345542b80d165eb59c5dbbf Mon Sep 17 00:00:00 2001 From: Richard Fearn Date: Thu, 5 Feb 2015 11:53:33 +0100 Subject: [PATCH 1/2] catools: make `caget -lb` output '0' instead of empty string for zero value --- src/catools/tool_lib.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/catools/tool_lib.c b/src/catools/tool_lib.c index 71b444ccb..6ad1a8b56 100644 --- a/src/catools/tool_lib.c +++ b/src/catools/tool_lib.c @@ -68,17 +68,21 @@ void sprint_long (char *ret, long val, IntFormatT outType) case hex: sprintf(ret, "0x%lX", val); break; case oct: sprintf(ret, "0o%lo", val); break; case bin: - for (i=31; i>=0 ; i--) - { - bit = (val>>i) & 0x1L; - if (skip<0 && bit) + if (val == 0) { + sprintf(ret, "0"); + } else { + for (i=31; i>=0 ; i--) { - skip = 31 - i; /* skip leading 0's */ - ret[i+1] = '\0'; - } - if (skip >= 0) - { - ret[31-i-skip] = (bit) ? '1' : '0'; + bit = (val>>i) & 0x1L; + if (skip<0 && bit) + { + skip = 31 - i; /* skip leading 0's */ + ret[i+1] = '\0'; + } + if (skip >= 0) + { + ret[31-i-skip] = (bit) ? '1' : '0'; + } } } break; From 02aa7e2f73293ada08705523ce4d393bda25c249 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 10 Feb 2015 18:10:33 -0600 Subject: [PATCH 2/2] 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 {