From 5bcd8e3fe7c6780e013466405d9e1ebf529a8561 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Sat, 2 Nov 1996 00:51:12 +0000 Subject: [PATCH] many pc port, const in API, and other changes --- src/ca/access.c | 418 ++++++++++++++++++++++------------------- src/ca/acctst.c | 225 +++++++++++++++------- src/ca/addrList.h | 6 +- src/ca/bsd_depen.c | 8 +- src/ca/caRepeater.c | 3 +- src/ca/cadef.h | 256 +++++++++++++------------ src/ca/caerr.h | 2 +- src/ca/catime.c | 4 +- src/ca/conn.c | 13 +- src/ca/convert.c | 21 +++ src/ca/if_depen.c | 40 ++-- src/ca/iocinf.c | 82 ++++---- src/ca/iocinf.h | 88 ++++++--- src/ca/iocmsg.h | 185 ------------------ src/ca/net_convert.h | 102 +++++++++- src/ca/os_depen.h | 176 +---------------- src/ca/posix_depen.c | 10 +- src/ca/repeater.c | 55 +++--- src/ca/service.c | 111 ++++++----- src/ca/syncgrp.c | 7 +- src/ca/vxWorks_depen.c | 17 +- src/ca/windows_depen.c | 38 ++-- src/include/cadef.h | 256 +++++++++++++------------ src/include/caerr.h | 2 +- 24 files changed, 1088 insertions(+), 1037 deletions(-) delete mode 100644 src/ca/iocmsg.h diff --git a/src/ca/access.c b/src/ca/access.c index 87211a98a..de848a476 100644 --- a/src/ca/access.c +++ b/src/ca/access.c @@ -99,6 +99,9 @@ /************************************************************************/ /* * $Log$ + * Revision 1.86 1996/09/16 16:41:47 jhill + * local except => except handler & ca vers str routine + * * Revision 1.85 1996/09/04 20:02:00 jhill * test for non-nill piiu under vxWorks * @@ -253,8 +256,8 @@ unsigned cmmd ); #ifdef vxWorks LOCAL void ca_event_handler( -evid monix, -struct db_addr *paddr, +miu monix, +struct dbAddr *paddr, int hold, void *pfl ); @@ -264,19 +267,19 @@ LOCAL void ca_pend_io_cleanup(); LOCAL void create_udp_fd(); static int issue_ca_array_put ( -unsigned cmd, -unsigned id, -chtype type, -unsigned long count, -chid chix, -void *pvalue +unsigned cmd, +unsigned id, +chtype type, +unsigned long count, +chid chix, +const void *pvalue ); LOCAL void ca_default_exception_handler(struct exception_handler_args args); LOCAL int cac_push_msg( struct ioc_in_use *piiu, -caHdr *pmsg, -void *pext +caHdr *pmsg, +const void *pext ); LOCAL void cac_add_msg (IIU *piiu); @@ -286,7 +289,9 @@ LOCAL void *malloc_put_convert(unsigned long size); LOCAL void free_put_convert(void *pBuf); #endif -LOCAL evid caIOBlockCreate(void); +LOCAL miu caIOBlockCreate(void); + +LOCAL int check_a_dbr_string(const char *pStr, const unsigned count); /* @@ -299,8 +304,8 @@ LOCAL evid caIOBlockCreate(void); */ LOCAL int cac_push_msg( struct ioc_in_use *piiu, -caHdr *pmsg, -void *pext +caHdr *pmsg, +const void *pext ) { caHdr msg; @@ -682,7 +687,7 @@ LOCAL void create_udp_fd() * Modify or override the default * client host name. */ -int epicsShareAPI ca_modify_host_name(char *pHostName) +int epicsShareAPI ca_modify_host_name(const char *pHostName) { char *pTmp; unsigned size; @@ -737,7 +742,7 @@ int epicsShareAPI ca_modify_host_name(char *pHostName) * Modify or override the default * client user name. */ -int epicsShareAPI ca_modify_user_name(char *pClientName) +int epicsShareAPI ca_modify_user_name(const char *pClientName) { char *pTmp; unsigned size; @@ -834,7 +839,7 @@ void ca_process_exit() while(piiu){ if(ca_static->ca_fd_register_func){ (*ca_static->ca_fd_register_func)( - ca_static->ca_fd_register_arg, + (void *)ca_static->ca_fd_register_arg, piiu->sock_chan, FALSE); } @@ -932,14 +937,12 @@ void ca_process_exit() UNLOCK; } - - /* * - * CA_BUILD_AND_CONNECT + * CA_BUILD_AND_CONNECT * - * backwards compatible entry point to ca_search_and_connect() + * backwards compatible entry point to ca_search_and_connect() */ int epicsShareAPI ca_build_and_connect ( @@ -952,32 +955,30 @@ int epicsShareAPI ca_build_and_connect void *puser ) { - if(get_type != TYPENOTCONN && pvalue!=0 && get_count!=0){ - return ECA_ANACHRONISM; - } - - return ca_search_and_connect(name_str,chixptr,conn_func,puser); + if(get_type != TYPENOTCONN && pvalue!=0 && get_count!=0){ + return ECA_ANACHRONISM; + } + + return ca_search_and_connect(name_str,chixptr,conn_func,puser); } + /* - * * ca_search_and_connect() - * - * */ int epicsShareAPI ca_search_and_connect ( - char *name_str, - chid *chixptr, - void (*conn_func) (struct connection_handler_args), - void *puser + const char *name_str, + chid *chixptr, + void (*conn_func) (struct connection_handler_args), + const void *puser ) { - long status; - chid chix; - int strcnt; - int sec; + long status; + ciu chix; + int strcnt; + int sec; /* * make sure that chix is NULL on fail @@ -998,7 +999,7 @@ int epicsShareAPI ca_search_and_connect */ #ifdef vxWorks { - struct db_addr tmp_paddr; + struct dbAddr tmp_paddr; /* Find out quickly if channel is on this node */ status = db_name_to_addr(name_str, &tmp_paddr); @@ -1012,17 +1013,17 @@ int epicsShareAPI ca_search_and_connect * block */ size = CA_MESSAGE_ALIGN(sizeof(*chix) + strcnt) + - sizeof(struct db_addr); - *chixptr = chix = (chid) calloc(1,size); + sizeof(struct dbAddr); + *chixptr = chix = (ciu) calloc(1,size); if (!chix){ return ECA_ALLOCMEM; } - chix->id.paddr = (struct db_addr *) + chix->id.paddr = (struct dbAddr *) (CA_MESSAGE_ALIGN(sizeof(*chix)+strcnt) + (char *)chix); *chix->id.paddr = tmp_paddr; chix->puser = puser; chix->pConnFunc = conn_func; - chix->type = chix->id.paddr->field_type; + chix->type = chix->id.paddr->dbr_field_type; chix->count = chix->id.paddr->no_elements; chix->piiu = NULL; /* none */ chix->state = cs_conn; @@ -1066,7 +1067,7 @@ int epicsShareAPI ca_search_and_connect /* allocate CHIU (channel in use) block */ /* also allocate enough for the channel name */ - *chixptr = chix = (chid) calloc(1, sizeof(*chix) + strcnt); + *chixptr = chix = (ciu) calloc(1, sizeof(*chix) + strcnt); if (!chix){ return ECA_ALLOCMEM; } @@ -1139,14 +1140,14 @@ int epicsShareAPI ca_search_and_connect * */ int search_msg( -chid chix, -int reply_type +ciu chix, +int reply_type ) { int status; int size; int cmd; - caHdr *mptr; + caHdr *mptr; struct ioc_in_use *piiu; piiu = chix->piiu; @@ -1206,8 +1207,8 @@ chid chix, void *pvalue ) { - int status; - evid monix; + int status; + miu monix; CHIXCHK(chix); @@ -1291,11 +1292,11 @@ chtype type, unsigned long count, chid chix, void (*pfunc) (struct event_handler_args), -void *arg +const void *arg ) { int status; - evid monix; + miu monix; CHIXCHK(chix); @@ -1364,19 +1365,19 @@ void *arg /* * caIOBlockCreate() */ -LOCAL evid caIOBlockCreate(void) +LOCAL miu caIOBlockCreate(void) { int status; - evid pIOBlock; + miu pIOBlock; LOCK; - pIOBlock = (evid) ellGet (&free_event_list); + pIOBlock = (miu) ellGet (&free_event_list); if (pIOBlock) { memset ((char *)pIOBlock, 0, sizeof(*pIOBlock)); } else { - pIOBlock = (evid) calloc(1, sizeof(*pIOBlock)); + pIOBlock = (miu) calloc(1, sizeof(*pIOBlock)); } if (pIOBlock) { @@ -1403,7 +1404,7 @@ LOCAL evid caIOBlockCreate(void) /* * caIOBlockFree() */ -void caIOBlockFree(evid pIOBlock) +void caIOBlockFree(miu pIOBlock) { int status; @@ -1427,21 +1428,21 @@ chid chan, int cbRequired, int status) { - evid monix; - evid next; + miu monix; + miu next; struct event_handler_args args; - for (monix = (evid) ellFirst (pList); + for (monix = (miu) ellFirst (pList); monix; monix = next) { - next = (evid) ellNext (&monix->node); + next = (miu) ellNext (&monix->node); if (chan == NULL || monix->chan == chan) { ellDelete (pList, &monix->node); - args.usr = monix->usr_arg; + args.usr = (void *) monix->usr_arg; args.chid = monix->chan; args.type = monix->type; args.count = monix->count; @@ -1516,14 +1517,14 @@ int epicsShareAPI ca_array_put_callback chtype type, unsigned long count, chid chix, -void *pvalue, +const void *pvalue, void (*pfunc)(struct event_handler_args), -void *usrarg +const void *usrarg ) { IIU *piiu; int status; - evid monix; + miu monix; /* * valid channel id test @@ -1555,15 +1556,25 @@ void *usrarg } } + if (type==DBR_STRING) { + int status; + status = check_a_dbr_string(pvalue, count); + if (status != ECA_NORMAL) { + return status; + } + } + #ifdef vxWorks if (!piiu) { + /* cast removes const */ + ciu pChan = (ciu) chix; CACLIENTPUTNOTIFY *ppn; unsigned size; size = dbr_size_n(type,count); LOCK; - ppn = chix->ppn; + ppn = pChan->ppn; if(ppn){ /* * wait while it is busy @@ -1585,7 +1596,7 @@ void *usrarg */ if(ppn->valueSizeppn = NULL; + ppn = pChan->ppn = NULL; } } @@ -1596,17 +1607,17 @@ void *usrarg UNLOCK; return ECA_ALLOCMEM; } - chix->ppn = ppn; + pChan->ppn = ppn; ppn->pcas = ca_static; ppn->dbPutNotify.userCallback = ca_put_notify_action; - ppn->dbPutNotify.usrPvt = chix; + ppn->dbPutNotify.usrPvt = pChan; ppn->dbPutNotify.paddr = chix->id.paddr; ppn->dbPutNotify.pbuffer = (ppn+1); } ppn->busy = TRUE; ppn->caUserCallback = pfunc; - ppn->caUserArg = usrarg; + ppn->caUserArg = (void *) usrarg; ppn->dbPutNotify.nRequest = count; memcpy(ppn->dbPutNotify.pbuffer, (char *)pvalue, size); status = dbPutNotifyMapType(&ppn->dbPutNotify, type); @@ -1634,7 +1645,7 @@ void *usrarg * reclaiming the resource */ LOCK; - monix = (evid) caIOBlockCreate(); + monix = caIOBlockCreate(); if (!monix) { UNLOCK; return ECA_ALLOCMEM; @@ -1725,10 +1736,10 @@ LOCAL void ca_put_notify_action(PUTNOTIFY *ppn) * */ int epicsShareAPI ca_array_put ( -chtype type, -unsigned long count, -chid chix, -void *pvalue + chtype type, + unsigned long count, + chid chix, + const void *pvalue ) { /* @@ -1753,6 +1764,14 @@ void *pvalue if(count > chix->count || count == 0) return ECA_BADCOUNT; + if (type==DBR_STRING) { + int status; + status = check_a_dbr_string(pvalue, count); + if (status != ECA_NORMAL) { + return status; + } + } + #ifdef vxWorks /* * If channel is on this client's host then @@ -1775,18 +1794,41 @@ void *pvalue return issue_ca_array_put(CA_PROTO_WRITE, ~0U, type, count, chix, pvalue); } +/* + * check_a_dbr_string() + */ +LOCAL int check_a_dbr_string(const char *pStr, const unsigned count) +{ + unsigned i; + + for (i=0; i< count; i++) { + unsigned int strsize; + + strsize = strlen(pStr) + 1; + + if (strsize>MAX_STRING_SIZE) { + return ECA_STRTOBIG; + } + + pStr += MAX_STRING_SIZE; + } + + return ECA_NORMAL; +} + + /* * issue_ca_array_put() */ LOCAL int issue_ca_array_put ( -unsigned cmd, -unsigned id, -chtype type, -unsigned long count, -chid chix, -void *pvalue +unsigned cmd, +unsigned id, +chtype type, +unsigned long count, +chid chix, +const void *pvalue ) { int status; @@ -1804,28 +1846,10 @@ void *pvalue size_of_one = dbr_size[type]; postcnt = dbr_size_n(type,count); - /* - * - * Each of their strings is checked for prpoper size - * so there is no chance that they could crash the - * CA server. - */ - if(type == DBR_STRING){ + if(type == DBR_STRING && count == 1){ char *pstr = (char *)pvalue; - if(count == 1) - postcnt = strlen(pstr)+1; - - for(i=0; i< count; i++){ - unsigned int strsize; - - strsize = strlen(pstr) + 1; - - if(strsize>size_of_one) - return ECA_STRTOBIG; - - pstr += size_of_one; - } + postcnt = strlen(pstr)+1; } # ifdef CONVERSION_REQUIRED @@ -1971,23 +1995,24 @@ chid chix, void (*pfunc)(struct connection_handler_args) ) { + ciu pChan = (ciu) chix; /* remove const */ INITCHK; - LOOSECHIXCHK(chix); + LOOSECHIXCHK(pChan); - if(chix->pConnFunc == pfunc) + if(pChan->pConnFunc == pfunc) return ECA_NORMAL; LOCK; - if(chix->type == TYPENOTCONN){ - if(!chix->pConnFunc && chix->state==cs_never_conn){ - CLRPENDRECV(FALSE); + if(pChan->type == TYPENOTCONN){ + if(!pChan->pConnFunc && pChan->state==cs_never_conn){ + CLRPENDRECV; } if(!pfunc){ SETPENDRECV; } } - chix->pConnFunc = pfunc; + pChan->pConnFunc = pfunc; UNLOCK; return ECA_NORMAL; @@ -2001,20 +2026,21 @@ int epicsShareAPI ca_replace_access_rights_event( chid chan, void (*pfunc)(struct access_rights_handler_args)) { + ciu pChan = (ciu) chan; /* remove const */ struct access_rights_handler_args args; INITCHK; - LOOSECHIXCHK(chan); + LOOSECHIXCHK(pChan); - chan->pAccessRightsFunc = pfunc; + pChan->pAccessRightsFunc = pfunc; /* * make certain that it runs at least once */ - if(chan->state == cs_conn && chan->pAccessRightsFunc){ + if(pChan->state == cs_conn && pChan->pAccessRightsFunc){ args.chid = chan; args.ar = chan->ar; - (*chan->pAccessRightsFunc)(args); + (*pChan->pAccessRightsFunc)(args); } return ECA_NORMAL; @@ -2027,24 +2053,24 @@ void (*pfunc)(struct access_rights_handler_args)) */ int epicsShareAPI ca_add_exception_event ( -void (*pfunc)(struct exception_handler_args), -void *arg + void (*pfunc)(struct exception_handler_args), + const void *arg ) { - INITCHK; - LOCK; - if(pfunc){ - ca_static->ca_exception_func = pfunc; - ca_static->ca_exception_arg = arg; - } - else{ - ca_static->ca_exception_func = ca_default_exception_handler; - ca_static->ca_exception_arg = NULL; - } - UNLOCK; + INITCHK; + LOCK; + if (pfunc) { + ca_static->ca_exception_func = pfunc; + ca_static->ca_exception_arg = arg; + } + else { + ca_static->ca_exception_func = ca_default_exception_handler; + ca_static->ca_exception_arg = NULL; + } + UNLOCK; - return ECA_NORMAL; + return ECA_NORMAL; } @@ -2099,7 +2125,7 @@ chtype type, unsigned long count, chid chix, void (*ast)(struct event_handler_args), -void *astarg, +const void *astarg, ca_real p_delta, ca_real n_delta, ca_real timeout, @@ -2107,11 +2133,12 @@ evid *monixptr, long mask ) { - evid monix; - int status; + ciu pChan = (ciu) chix; /* remove const */ + miu monix; + int status; INITCHK; - LOOSECHIXCHK(chix); + LOOSECHIXCHK(pChan); if(INVALID_DB_REQ(type)) return ECA_BADTYPE; @@ -2140,7 +2167,7 @@ long mask */ LOCK; - if (!chix->piiu) { + if (!pChan->piiu) { # ifdef vxWorks int size; static int dbevsize; @@ -2149,8 +2176,8 @@ long mask dbevsize = db_sizeof_event_block(); } size = sizeof(*monix)+dbevsize; - if(!(monix = (evid)ellGet(&dbfree_ev_list))){ - monix = (evid)malloc(size); + if(!(monix = (miu)ellGet(&dbfree_ev_list))){ + monix = (miu)malloc(size); } # else return ECA_INTERNAL; @@ -2181,10 +2208,10 @@ long mask monix->mask = (unsigned short) mask; # ifdef vxWorks - if(!chix->piiu){ + if(!pChan->piiu){ status = db_add_event( evuser, - chix->id.paddr, + pChan->id.paddr, ca_event_handler, monix, mask, @@ -2200,7 +2227,7 @@ long mask * is no chance that it will be deleted * at exit before it is completely created */ - ellAdd(&chix->eventq, &monix->node); + ellAdd(&pChan->eventq, &monix->node); /* * force event to be called at least once @@ -2219,16 +2246,16 @@ long mask /* It can be added to the list any place if it is remote */ /* Place in the channel list */ - ellAdd(&chix->eventq, &monix->node); + ellAdd(&pChan->eventq, &monix->node); UNLOCK; - if(chix->state == cs_conn){ + if(pChan->state == cs_conn){ status = ca_request_event(monix); if (status != ECA_NORMAL) { LOCK; - if (ca_state(chix)==cs_conn) { - ellDelete (&chix->eventq, &monix->node); + if (ca_state(pChan)==cs_conn) { + ellDelete (&pChan->eventq, &monix->node); caIOBlockFree(monix); } UNLOCK @@ -2310,8 +2337,8 @@ int ca_request_event(evid monix) */ #ifdef vxWorks LOCAL void ca_event_handler( -evid monix, -struct db_addr *paddr, +miu monix, +struct dbAddr *paddr, int hold, void *pfl ) @@ -2339,7 +2366,7 @@ void *pfl count = monix->count; } - if(type == paddr->field_type){ + if(type == paddr->dbr_field_type){ pval = paddr->pfield; status = OK; } @@ -2398,7 +2425,7 @@ void *pfl if (monix->usr_func) { struct event_handler_args args; - args.usr = monix->usr_arg; + args.usr = (void *) monix->usr_arg; args.chid = monix->chan; args.type = type; args.count = count; @@ -2464,10 +2491,11 @@ void *pfl */ int epicsShareAPI ca_clear_event (evid monix) { - int status; - chid chix = monix->chan; + ciu chix = (ciu) monix->chan; /* cast removes const */ + miu pMon = (miu) monix; /* cast removes const */ + int status; caHdr hdr; - evid lkup; + evid lkup; /* * is it a valid channel ? @@ -2481,15 +2509,15 @@ int epicsShareAPI ca_clear_event (evid monix) LOCK; lkup = (evid) bucketLookupItemUnsignedId( pFastBucket, - &monix->id); + &pMon->id); UNLOCK; - if (lkup != monix) { + if (lkup != pMon) { return ECA_BADMONID; } } /* disable any further events from this event block */ - monix->usr_func = NULL; + pMon->usr_func = NULL; #ifdef vxWorks if (!chix->piiu) { @@ -2499,9 +2527,9 @@ int epicsShareAPI ca_clear_event (evid monix) * dont allow two threads to delete the same moniitor at once */ LOCK; - ellDelete(&chix->eventq, &monix->node); - status = db_cancel_event(monix + 1); - ellAdd(&dbfree_ev_list, &monix->node); + ellDelete(&chix->eventq, &pMon->node); + status = db_cancel_event(pMon + 1); + ellAdd(&dbfree_ev_list, &pMon->node); UNLOCK; return ECA_NORMAL; @@ -2521,7 +2549,7 @@ int epicsShareAPI ca_clear_event (evid monix) /* msg header */ hdr.m_cmmd = htons(CA_PROTO_EVENT_CANCEL); - hdr.m_available = monix->id; + hdr.m_available = pMon->id; hdr.m_type = htons(chix->type); hdr.m_count = htons(chix->count); hdr.m_cid = chix->id.sid; @@ -2536,8 +2564,8 @@ int epicsShareAPI ca_clear_event (evid monix) } else{ LOCK; - ellDelete(&monix->chan->eventq, &monix->node); - caIOBlockFree(monix); + ellDelete(&chix->eventq, &pMon->node); + caIOBlockFree(pMon); UNLOCK; status = ECA_NORMAL; } @@ -2563,50 +2591,51 @@ int epicsShareAPI ca_clear_event (evid monix) */ int epicsShareAPI ca_clear_channel (chid chix) { - int status; - evid monix; - struct ioc_in_use *piiu = chix->piiu; + ciu pChan = (ciu) chix; /* remove const */ + miu monix; + int status; + struct ioc_in_use *piiu = chix->piiu; caHdr hdr; - enum channel_state old_chan_state; + enum channel_state old_chan_state; - LOOSECHIXCHK(chix); + LOOSECHIXCHK(pChan); /* disable their further use of deallocated channel */ - chix->type = TYPENOTINUSE; - old_chan_state = chix->state; - chix->state = cs_closed; - chix->pAccessRightsFunc = NULL; - chix->pConnFunc = NULL; + pChan->type = TYPENOTINUSE; + old_chan_state = pChan->state; + pChan->state = cs_closed; + pChan->pAccessRightsFunc = NULL; + pChan->pConnFunc = NULL; /* the while is only so I can break to the lock exit */ LOCK; /* disable any further events from this channel */ - for (monix = (evid) chix->eventq.node.next; + for (monix = (miu) pChan->eventq.node.next; monix; - monix = (evid) monix->node.next) + monix = (miu) monix->node.next) monix->usr_func = NULL; /* disable any further get callbacks from this channel */ - for (monix = (evid) pend_read_list.node.next; + for (monix = (miu) pend_read_list.node.next; monix; - monix = (evid) monix->node.next) + monix = (miu) monix->node.next) if (monix->chan == chix) monix->usr_func = NULL; /* disable any further put callbacks from this channel */ - for (monix = (evid) pend_write_list.node.next; + for (monix = (miu) pend_write_list.node.next; monix; - monix = (evid) monix->node.next) + monix = (miu) monix->node.next) if (monix->chan == chix) monix->usr_func = NULL; #ifdef vxWorks - if (!chix->piiu) { + if (!pChan->piiu) { CACLIENTPUTNOTIFY *ppn; int status; /* * clear out the events for this channel */ - while (monix = (evid) ellGet(&chix->eventq)) { + while ( (monix = (miu) ellGet(&pChan->eventq)) ) { status = db_cancel_event(monix + 1); assert (status == OK); ellAdd(&dbfree_ev_list, &monix->node); @@ -2615,8 +2644,8 @@ int epicsShareAPI ca_clear_channel (chid chix) /* * cancel any outstanding put notifies */ - if(chix->ppn){ - ppn = chix->ppn; + if(pChan->ppn){ + ppn = pChan->ppn; if(ppn->busy){ dbNotifyCancel(&ppn->dbPutNotify); } @@ -2626,23 +2655,32 @@ int epicsShareAPI ca_clear_channel (chid chix) /* * clear out this channel */ - ellDelete(&local_chidlist, &chix->node); - free((char *) chix); + ellDelete(&local_chidlist, &pChan->node); + free((char *) pChan); UNLOCK; return ECA_NORMAL; } #endif + /* + * if this channel does not have a connection handler + * and it has not connected for the first time then clear the + * outstanding IO count + */ + if (old_chan_state == cs_never_conn && !chix->pConnFunc) { + CLRPENDRECV; + } + /* * dont send the message if not conn * (just delete from the queue and return) * * check for conn state while locked to avoid a race */ - if(old_chan_state != cs_conn){ + if (old_chan_state != cs_conn) { UNLOCK; - clearChannelResources (chix->cid); + clearChannelResources (pChan->cid); return ECA_NORMAL; } @@ -2653,8 +2691,8 @@ int epicsShareAPI ca_clear_channel (chid chix) /* msg header */ hdr.m_cmmd = htons(CA_PROTO_CLEAR_CHANNEL); - hdr.m_available = chix->cid; - hdr.m_cid = chix->id.sid; + hdr.m_available = pChan->cid; + hdr.m_cid = pChan->id.sid; hdr.m_type = htons(0); hdr.m_count = htons(0); hdr.m_postsize = 0; @@ -2678,7 +2716,7 @@ int epicsShareAPI ca_clear_channel (chid chix) void clearChannelResources(unsigned id) { struct ioc_in_use *piiu; - chid chix; + ciu chix; int status; LOCK; @@ -2982,7 +3020,7 @@ void generateLocalExceptionWithFileAndLine (long stat, char *ctx, return; } - args.usr = ca_static->ca_exception_arg; + args.usr = (void *) ca_static->ca_exception_arg; args.chid = NULL; args.type = -1; args.count = 0u; @@ -3002,7 +3040,7 @@ void generateLocalExceptionWithFileAndLine (long stat, char *ctx, /* * CA_SIGNAL() */ -void epicsShareAPI ca_signal(long ca_status,char *message) +void epicsShareAPI ca_signal(long ca_status, const char *message) { ca_signal_with_file_and_lineno(ca_status, message, NULL, 0); } @@ -3038,11 +3076,11 @@ READONLY char * epicsShareAPI ca_message (long ca_status) */ void epicsShareAPI ca_signal_with_file_and_lineno( long ca_status, -char *message, -char *pfilenm, +const char *message, +const char *pfilenm, int lineno) { - static char *severity[] = + static const char *severity[] = { "Warning", "Success", @@ -3308,9 +3346,9 @@ void issue_identify_client(struct ioc_in_use *piiu) */ void issue_claim_channel(struct ioc_in_use *piiu, chid pchan) { - caHdr hdr; + caHdr hdr; unsigned size; - char *pName; + const char *pName; if(!piiu){ return; @@ -3360,7 +3398,7 @@ void issue_claim_channel(struct ioc_in_use *piiu, chid pchan) */ LOCAL void ca_default_exception_handler(struct exception_handler_args args) { - char *pCtx; + const char *pCtx; /* * LOCK around use of sprintf buffer @@ -3393,7 +3431,7 @@ LOCAL void ca_default_exception_handler(struct exception_handler_args args) * (for a manager of the select system call under UNIX) * */ -int epicsShareAPI ca_add_fd_registration(CAFDHANDLER *func, void *arg) +int epicsShareAPI ca_add_fd_registration(CAFDHANDLER *func, const void *arg) { fd_register_func = func; fd_register_arg = arg; @@ -3424,7 +3462,7 @@ int ca_defunct() * currently implemented as a function * (may be implemented as a MACRO in the future) */ -char * epicsShareAPI ca_host_name_function(chid chix) +READONLY char * epicsShareAPI ca_host_name_function(chid chix) { IIU *piiu; @@ -3489,7 +3527,7 @@ int ca_channel_status(int tid) piiu = (struct ioc_in_use *) pcas->ca_iiuList.node.next; while(piiu){ chix = (chid) &piiu->chidlist.node; - while (chix = (chid) chix->node.next){ + while ( (chix = (chid) chix->node.next) ){ printf( "%s native type=%d ", ca_name(chix), ca_field_type(chix)); diff --git a/src/ca/acctst.c b/src/ca/acctst.c index f55a05dfc..ae64da196 100644 --- a/src/ca/acctst.c +++ b/src/ca/acctst.c @@ -64,6 +64,18 @@ int conn_cb_count; #define min(A,B) ((A)>(B)?(B):(A)) #endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NELEMENTS +#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) +#endif + int doacctst(char *pname); void test_sync_groups(chid chix); void multiple_sg_requests(chid chix, CA_SYNC_GID gid); @@ -137,6 +149,7 @@ int doacctst(char *pname) evid monix; char pstring[NUM][MAX_STRING_SIZE]; unsigned size; + unsigned monCount=0u; SEVCHK(ca_task_initialize(), "Unable to initialize"); @@ -210,14 +223,9 @@ int doacctst(char *pname) &chix2); SEVCHK(status, NULL); - status = ca_build_and_connect( - pname, - TYPENOTCONN, - 0, - &chix1, - NULL, - NULL, - NULL); + status = ca_search( + pname, + &chix1); SEVCHK(status, NULL); if (ca_test_io() == ECA_IOINPROGRESS) { @@ -252,49 +260,95 @@ int doacctst(char *pname) } printf("\n"); + /* + * look for problems with ca_search(), ca_clear_channel(), + * ca_change_connection_event(), and ca_pend_io(() combo + */ status = ca_search(pname,& chix3); SEVCHK(status, NULL); + status = ca_replace_access_rights_event(chix3, accessSecurity_cb); + SEVCHK(status, NULL); /* * verify clear before connect */ - status = ca_search_and_connect(pname, &chix4, CONN_ROUTINE, NULL); + status = ca_search(pname, &chix4); SEVCHK(status, NULL); status = ca_clear_channel(chix4); SEVCHK(status, NULL); - status = ca_search_and_connect(pname, &chix4, CONN_ROUTINE, NULL); + status = ca_search(pname, &chix4); SEVCHK(status, NULL); status = ca_replace_access_rights_event(chix4, accessSecurity_cb); SEVCHK(status, NULL); - status = ca_search_and_connect(pname, &chix2, CONN_ROUTINE, NULL); + status = ca_search(pname, &chix2); SEVCHK(status, NULL); status = ca_replace_access_rights_event(chix2, accessSecurity_cb); SEVCHK(status, NULL); - status = ca_search_and_connect(pname, &chix1, CONN_ROUTINE, NULL); + status = ca_search(pname, &chix1); SEVCHK(status, NULL); status = ca_replace_access_rights_event(chix1, accessSecurity_cb); SEVCHK(status, NULL); + status = ca_change_connection_event(chix1,conn); + SEVCHK(status, NULL); + + status = ca_change_connection_event(chix1,NULL); + SEVCHK(status, NULL); + + status = ca_change_connection_event(chix1,conn); + SEVCHK(status, NULL); + + status = ca_change_connection_event(chix1,NULL); + SEVCHK(status, NULL); + status = ca_pend_io(1000.0); SEVCHK(status, NULL); - assert(ca_state(chix1) == cs_conn); - assert(ca_state(chix2) == cs_conn); - assert(ca_state(chix3) == cs_conn); - assert(ca_state(chix4) == cs_conn); + assert (ca_state(chix1) == cs_conn); + assert (ca_state(chix2) == cs_conn); + assert (ca_state(chix3) == cs_conn); + assert (ca_state(chix4) == cs_conn); - assert(INVALID_DB_REQ(chix1->type) == FALSE); - assert(INVALID_DB_REQ(chix2->type) == FALSE); - assert(INVALID_DB_REQ(chix3->type) == FALSE); - assert(INVALID_DB_REQ(chix4->type) == FALSE); + assert (INVALID_DB_REQ(chix1->type) == FALSE); + assert (INVALID_DB_REQ(chix2->type) == FALSE); + assert (INVALID_DB_REQ(chix3->type) == FALSE); + assert (INVALID_DB_REQ(chix4->type) == FALSE); + + /* + * verify connection handlers are working + */ + status = ca_clear_channel(chix1); + SEVCHK(status, NULL); + status = ca_clear_channel(chix2); + SEVCHK(status, NULL); + status = ca_clear_channel(chix3); + SEVCHK(status, NULL); + status = ca_clear_channel(chix4); + SEVCHK(status, NULL); + + status = ca_search_and_connect(pname, &chix1, conn, NULL); + SEVCHK(status, NULL); + status = ca_search_and_connect(pname, &chix2, conn, NULL); + SEVCHK(status, NULL); + status = ca_search_and_connect(pname, &chix3, conn, NULL); + SEVCHK(status, NULL); + status = ca_search_and_connect(pname, &chix4, conn, NULL); + SEVCHK(status, NULL); + + ca_pend_event(1.0); + while (conn_cb_count != 4){ + ca_pend_event(1.0); + printf("waiting on connect..."); + fflush(stdout); + } #ifdef VMS lib$show_timer(); @@ -308,6 +362,49 @@ int doacctst(char *pname) ca_read_access(chix1), ca_write_access(chix1)); + /* + * ca_pend_io() must block + */ + if(ca_read_access(chix4)){ + dbr_float_t req; + dbr_float_t resp; + + printf ("get TMO test ..."); + fflush(stdout); + req = 56.57f; + resp = -99.99f; + SEVCHK(ca_put(DBR_FLOAT, chix4, &req),NULL); + SEVCHK(ca_get(DBR_FLOAT, chix4, &resp),NULL); + status = ca_pend_io(1.0e-12); + if (status==ECA_NORMAL) { + if (resp != req) { + printf ( + "get block test failed - val written %f\n", req); + printf ( + "get block test failed - val read %f\n", resp); + assert(0); + } + } + else if (resp != -99.99f) { + printf ( + "CA didnt block for get to return?\n"); + } + + req = 33.44f; + resp = -99.99f; + SEVCHK (ca_put(DBR_FLOAT, chix4, &req),NULL); + SEVCHK (ca_get(DBR_FLOAT, chix4, &resp),NULL); + SEVCHK (ca_pend_io(2000.0),NULL); + if (resp != req) { + printf ( + "get block test failed - val written %f\n", req); + printf ( + "get block test failed - val read %f\n", resp); + assert(0); + } + printf ("done\n"); + } + /* * Verify that we can write and then read back * the same analog value (DBR_FLOAT) @@ -389,33 +486,6 @@ int doacctst(char *pname) printf ("done\n"); } - /* - * ca_pend_io() must block - */ - if(ca_read_access(chix4)){ - dbr_float_t req = 3.3F; - dbr_float_t resp = 0.0F; - - printf ("get TMO test ..."); - fflush(stdout); - SEVCHK(ca_put(DBR_FLOAT, chix4, &req),NULL); - SEVCHK(ca_get(DBR_FLOAT, chix4, &resp),NULL); - status = ca_pend_io(1.0e-12); - if (status==ECA_NORMAL) { - assert (resp == req); - } - else { - assert (resp == 0.0F); - } - - resp = 0.0F; - SEVCHK (ca_put(DBR_FLOAT, chix4, &req),NULL); - SEVCHK (ca_get(DBR_FLOAT, chix4, &resp),NULL); - SEVCHK (ca_pend_io(2000.0),NULL); - assert (resp == req); - printf ("done\n"); - } - /* * verify we dont jam up on many uninterrupted * solicitations @@ -485,7 +555,7 @@ int doacctst(char *pname) /* * verify we dont jam up on many uninterrupted - * solicitations + * put callback solicitations */ if(ca_write_access(chix1) && ca_v42_ok(chix1)){ unsigned count=0u; @@ -509,12 +579,37 @@ int doacctst(char *pname) printf("waiting..."); fflush(stdout); } + printf("done.\n"); } else{ printf("Skipped multiple put cb test - no write access\n"); } + /* + * verify that we detect that a large string has been written + */ + if(ca_write_access(chix1)){ + dbr_string_t stimStr; + dbr_string_t respStr; + memset(stimStr, 'a', sizeof(stimStr)); + status = ca_array_put(DBR_STRING, 1u, chix1, stimStr); + assert(status==ECA_STRTOBIG); + sprintf(stimStr, "%u", 8u); + status = ca_array_put(DBR_STRING, 1u, chix1, stimStr); + assert(status==ECA_NORMAL); + status = ca_array_get(DBR_STRING, 1u, chix1, respStr); + assert(status==ECA_NORMAL); + status = ca_pend_io(0.0); + assert(status==ECA_NORMAL); + printf( +"Test fails if stim \"%s\" isnt roughly equiv to resp \"%s\"\n", + stimStr, respStr); + } + else{ + printf("Skipped bad string test - no write access\n"); + } + if(ca_v42_ok(chix1)){ test_sync_groups(chix1); } @@ -525,16 +620,21 @@ int doacctst(char *pname) printf("Performing multiple monitor test..."); fflush(stdout); { + unsigned count=0u; evid mid[1000]; dbr_float_t temp; for(i=0; i 1000) { - printf("1000 occurred\n"); - i = 0; - } } @@ -871,6 +963,7 @@ void test_sync_groups(chid chix) status = ca_sg_create(&gid2); SEVCHK(status, NULL); + multiple_sg_requests(chix, gid2); multiple_sg_requests(chix, gid1); status = ca_sg_test(gid2); @@ -881,10 +974,12 @@ void test_sync_groups(chid chix) SEVCHK(status, "SYNC GRP1"); status = ca_sg_block(gid2, 500.0); SEVCHK(status, "SYNC GRP2"); + status = ca_sg_delete(gid2); SEVCHK(status, NULL); status = ca_sg_create(&gid2); SEVCHK(status, NULL); + multiple_sg_requests(chix, gid1); multiple_sg_requests(chix, gid2); status = ca_sg_block(gid1, 15.0); diff --git a/src/ca/addrList.h b/src/ca/addrList.h index 8f0e2289e..a61bffd5f 100644 --- a/src/ca/addrList.h +++ b/src/ca/addrList.h @@ -3,8 +3,7 @@ extern "C" { #endif - -#include +#include void caSetupAddrList( ELLLIST *pList, @@ -15,7 +14,8 @@ void caPrintAddrList(ELLLIST *pList); void caDiscoverInterfaces( ELLLIST *pList, SOCKET socket, - int port); + int port, + struct in_addr matchAddr); void caAddConfiguredAddr( ELLLIST *pList, diff --git a/src/ca/bsd_depen.c b/src/ca/bsd_depen.c index 38a0fa26a..94870010c 100644 --- a/src/ca/bsd_depen.c +++ b/src/ca/bsd_depen.c @@ -150,17 +150,17 @@ int cac_select_io(struct timeval *ptimeout, int flags) } if (status<0) { - if (MYERRNO == EINTR) { + if (SOCKERRNO == EINTR) { } - else if (MYERRNO == EWOULDBLOCK) { + else if (SOCKERRNO == EWOULDBLOCK) { ca_printf("CAC: blocked at select ?\n"); } - else if (MYERRNO == ESRCH) { + else if (SOCKERRNO == ESRCH) { } else { ca_printf ( "CAC: unexpected select fail: %s\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } } diff --git a/src/ca/caRepeater.c b/src/ca/caRepeater.c index 02902a7c3..6f22005ed 100644 --- a/src/ca/caRepeater.c +++ b/src/ca/caRepeater.c @@ -21,9 +21,10 @@ #include -main() +int main() { ca_repeater (); assert (0); return (0); } + diff --git a/src/ca/cadef.h b/src/ca/cadef.h index d5e646b8c..8a5c4c4a4 100644 --- a/src/ca/cadef.h +++ b/src/ca/cadef.h @@ -121,8 +121,18 @@ HDRVERSIONID(cadefh, "@(#) $Id$") */ #define ca_field_type(CHID) ((CHID)->type) #define ca_element_count(CHID) ((CHID)->count) -#define ca_name(CHID) ((char *)((CHID)+1)) -#define ca_puser(CHID) ((CHID)->puser) +#define ca_name(CHID) ((READONLY char *)((CHID)+1)) +/* + * the odd cast here removes const (and allows past practice + * of using ca_puser(CHID) as an lvalue. + */ +#define ca_puser(CHID) (*(void **)&((CHID)->puser)) +/* + * here is the preferred way to load the puser ptr associated with + * channel (the cast removes const) + */ +#define ca_set_puser(CHID,PUSER) \ +(((struct channel_in_use *)CHID)->puser=(PUSER)) #define ca_host_name(CHID) ca_host_name_function(CHID) #define ca_read_access(CHID) ((CHID)->ar.read_access) #define ca_write_access(CHID) ((CHID)->ar.write_access) @@ -147,7 +157,8 @@ typedef struct ca_access_rights{ /* Format for the arguments to user connection handlers */ struct channel_in_use; struct connection_handler_args{ - struct channel_in_use *chid; /* Channel id */ + READONLY struct channel_in_use + *chid; /* Channel id */ long op; /* External codes for CA op */ }; @@ -159,7 +170,8 @@ typedef void caCh(); /* Format for the arguments to user access rights handlers */ struct access_rights_handler_args{ - struct channel_in_use *chid; /* Channel id */ + READONLY struct channel_in_use + *chid; /* Channel id */ caar ar; /* New access rights state */ }; @@ -176,9 +188,9 @@ struct channel_in_use{ unsigned short count; /* array element count */ union{ unsigned sid; /* server id */ - struct db_addr *paddr; /* database address */ + struct dbAddr *paddr; /* database address */ } id; - void *puser; /* user available area */ + READONLY void *puser; /* user available area */ enum channel_state state; /* connected/ disconnected etc */ caar ar; /* access rights */ @@ -200,10 +212,10 @@ struct channel_in_use{ */ }; -typedef struct channel_in_use *chid; -typedef long chtype; -typedef struct pending_event *evid; -typedef double ca_real; +typedef READONLY struct channel_in_use *chid; +typedef long chtype; +typedef READONLY struct pending_event *evid; +typedef double ca_real; /* The conversion routine to call for each type */ #define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE) @@ -211,34 +223,35 @@ typedef double ca_real; /* argument passed to event handlers and callback handlers */ struct event_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use *chid; /* Channel id */ - long type; /* the type of the value returned */ - long count; /* the element count of the item returned */ - void *dbr; /* Pointer to the value returned */ - int status; /* CA Status of the op from server - CA V4.1 */ + void *usr; /* User argument supplied when event added */ + READONLY struct channel_in_use + *chid; /* Channel id */ + long type; /* the type of the value returned */ + long count; /* the element count of the item returned */ + READONLY void *dbr; /* Pointer to the value returned */ + int status; /* CA Status of the op from server - CA V4.1 */ }; struct pending_event{ - ELLNODE node; /* list ptrs */ + ELLNODE node; /* list ptrs */ #ifdef CAC_FUNC_PROTO - void (*usr_func)(struct event_handler_args args); + void (*usr_func)(struct event_handler_args args); #else /*CAC_FUNC_PROTO*/ - void (*usr_func)(); + void (*usr_func)(); #endif /*CAC_FUNC_PROTO*/ - void *usr_arg; - struct channel_in_use *chan; - chtype type; /* requested type for local CA */ - unsigned long count; /* requested count for local CA */ + READONLY void *usr_arg; + chid chan; + chtype type; /* requested type for local CA */ + unsigned long count; /* requested count for local CA */ /* * the following provide for reissuing a * disconnected monitor */ - ca_real p_delta; - ca_real n_delta; - ca_real timeout; - unsigned id; - unsigned short mask; + ca_real p_delta; + ca_real n_delta; + ca_real timeout; + unsigned id; + unsigned short mask; }; void epicsShareAPI ca_test_event @@ -250,16 +263,17 @@ void epicsShareAPI ca_test_event /* Format for the arguments to user exception handlers */ struct exception_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use *chid; /* Channel id */ - long type; /* Requested type for the operation */ - long count; /* Requested count for the operation */ - void *addr; /* User's address to write results of CA_OP_GET */ - long stat; /* Channel access std status code */ - long op; /* External codes for channel access operations */ - char *ctx; /* A character string containing context info */ - char *pFile; /* source file name (may be NULL) */ - unsigned lineNo; /* source file line number */ + void *usr; /* User argument supplied when event added */ + READONLY struct channel_in_use + *chid; /* Channel id */ + long type; /* Requested type for the operation */ + long count; /* Requested count for the operation */ + void *addr; /* User's address to write results of CA_OP_GET */ + long stat; /* Channel access std status code */ + long op; /* External codes for channel access operations */ + const char *ctx; /* A character string containing context info */ + const char *pFile; /* source file name (may be NULL) */ + unsigned lineNo; /* source file line number */ }; @@ -303,29 +317,9 @@ int epicsShareAPI ca_task_exit #endif /*CAC_FUNC_PROTO*/ ); - -/************************************************************************/ -/* Return a channel identification for the supplied channel name */ -/* (and attempt to create a virtual circuit) */ -/************************************************************************/ - -/* - * preferred search mechanism - */ -#define ca_search(NAME,CHIDPTR)\ -ca_search_and_connect(NAME, CHIDPTR, 0, 0) -/* ca_search - ( - Name IO Value - ---- -- ----- -char *, NAME R NULL term ASCII channel name string -chid * CHIDPTR RW channel index written here - ); -*/ - /************************************************************************ - * anachronistic entry points * - * **** Fetching a value while searching nolonger supported**** * + * anachronistic entry points * + * **** Fetching a value while searching nolonger supported**** * ************************************************************************/ #define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) @@ -334,54 +328,76 @@ ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) +/************************************************************************/ +/* Return a channel identification for the supplied channel name */ +/* (and attempt to create a virtual circuit) */ +/************************************************************************/ + /* - * preferred search mechanism + * preferred search request API + */ +#define ca_search(NAME,CHIDPTR)\ +ca_search_and_connect(NAME, CHIDPTR, 0, 0) +/* ca_search + ( + Name IO Value + ---- -- ----- +const char *, NAME R NULL term ASCII channel name string +chid * CHIDPTR RW channel index written here + ); +*/ + + +/* + * preferred search request API */ int epicsShareAPI ca_search_and_connect ( #ifdef CAC_FUNC_PROTO /* Name IO Value */ /* ---- -- ----- */ -char *,/* NAME R NULL term ASCII channel name string */ -chid *,/* CHIDPTR RW channel index written here */ +const char *, + /* NAME R NULL term ASCII channel name string */ +chid *, /* CHIDPTR RW channel index written here */ void (*)(struct connection_handler_args), /* PFUNC R the address of user's connection handler*/ -void * /* PUSER R placed in the channel's puser field */ +const void * + /* PUSER R placed in the channel's puser field */ #endif /*CAC_FUNC_PROTO*/ ); /************************************************************************ - * anachronistic entry point * - * **** Fetching a value while searching nolonger supported**** * + * anachronistic entry point * + * **** Fetching a value while searching nolonger supported**** * ************************************************************************/ int epicsShareAPI ca_build_and_connect - ( -#ifdef CAC_FUNC_PROTO - /* Name IO Value */ - /* ---- -- ----- */ -char *, /* NAME R NULL term ASCII channel name string */ -chtype, /* GET_TYPE R external channel type to get */ -unsigned/* (no get if invalid type) */ -long, /* GET_COUNT R array count to get */ -chid *, /* CHIDPTR RW channel index written here */ -void *, /* PVALUE W A pointer to a user supplied buffer */ + ( +#ifdef CAC_FUNC_PROTO + /* Name IO Value */ + /* ---- -- ----- */ +char *, /* NAME R NULL term ASCII channel name string */ +chtype, /* GET_TYPE R external channel type to get */ +unsigned/* (no get if invalid type) */ +long, /* GET_COUNT R array count to get */ +chid *, /* CHIDPTR RW channel index written here */ +void *, /* PVALUE W A pointer to a user supplied buffer */ void (*)(struct connection_handler_args), - /* PFUNC R the address of user's connection handler*/ -void * /* PUSER R placed in the channel's puser field */ + /* PFUNC R the address of user's connection handler*/ +void * /* PUSER R placed in the channel's puser field */ #endif /*CAC_FUNC_PROTO*/ - ); + ); int epicsShareAPI ca_change_connection_event ( #ifdef CAC_FUNC_PROTO -chid chix, +chid chan, void (*pfunc)(struct connection_handler_args) #endif /*CAC_FUNC_PROTO*/ ); int epicsShareAPI ca_replace_access_rights_event( #ifdef CAC_FUNC_PROTO -chid chix, +chid chan, void (*pfunc)(struct access_rights_handler_args) #endif /*CAC_FUNC_PROTO*/ ); @@ -395,7 +411,7 @@ int epicsShareAPI ca_add_exception_event ( #ifdef CAC_FUNC_PROTO void (*pfunc)(struct exception_handler_args), -void *arg +const void *arg #endif /*CAC_FUNC_PROTO*/ ); @@ -419,7 +435,7 @@ chid /* CHAN, R channel identifier */ C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -char * PVALUE R pointer to a binary value string +const char * PVALUE R pointer to a binary value string */ #define ca_rput(CHID,PVALUE)\ @@ -428,7 +444,8 @@ ca_array_put(DBR_FLOAT, 1, CHID, (PVALUE)) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -dbr_float_t * PVALUE R pointer to a real value +const dbr_float_t * + PVALUE R pointer to a real value */ #define ca_put(CHTYPE, CHID, PVALUE) ca_array_put(CHTYPE, 1, CHID, PVALUE) @@ -437,7 +454,7 @@ dbr_float_t * PVALUE R pointer to a real value ---- -- ----- chtype, TYPE R channel type chid, CHID R channel index -void * PVALUE R pointer to new channel value of type specified +const void * PVALUE R pointer to new channel value of type specified i.e. status = ca_put(DBF_INT,chid,&value) */ @@ -450,7 +467,8 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void * /* PVALUE R pointer to new channel value of type */ +const void * + /* PVALUE R pointer to new channel value of type */ /* specified. */ #endif /*CAC_FUNC_PROTO*/ ); @@ -472,10 +490,12 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void *, /* PVALUE R pointer to new channel value of type */ +const void *, + /* PVALUE R pointer to new channel value of type */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void * /* USRARG R An argument copied to the above function*/ +const void * + /* USRARG R An argument copied to the above function*/ #endif /*CAC_FUNC_PROTO*/ ); @@ -492,7 +512,7 @@ void * /* USRARG R An argument copied to the above function*/ C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -char * PVALUE W string value pointer +char * PVALUE W string value pointer */ #define ca_rget(CHID,PVALUE) ca_array_get(DBR_FLOAT, 1, CHID, PVALUE) @@ -536,8 +556,9 @@ ca_array_get_callback(DBR_STRING, 1, CHID, PFUNC, ARG) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ #define ca_rget_callback(CHID,PFUNC,ARG)\ @@ -547,8 +568,9 @@ ca_array_get_callback(DBR_FLOAT, 1, CHID, PFUNC, ARG) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ #define ca_get_callback(CHTYPE, CHID,PFUNC,ARG)\ @@ -558,8 +580,9 @@ C Type Name IO Value ------ ----- -- ----- chtype, TYPE R channel type chid, CHID R channel index -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ int epicsShareAPI ca_array_get_callback @@ -573,7 +596,8 @@ unsigned long, chid, /* CHID R channel index */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void * /* USRARG R An argument copied to the above function */ +const void * + /* USRARG R An argument copied to the above function */ #endif /*CAC_FUNC_PROTO*/ ); @@ -597,9 +621,9 @@ ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,0.0,0.0,0.0,EVID) /* Name IO Value ---- -- ----- chid, CHID R channel index -void -(*)(), USRFUNC R the address of a user supplied function -void *, USRARG R An argument copied to the above function +void (*)(struct event_handler_args), + USRFUNC R the address of a user supplied function +const void *, USRARG R An argument copied to the above function evid * EVIDPTR W An id to refer to this event by */ @@ -611,9 +635,9 @@ evid * EVIDPTR W An id to refer to this event by /* Name IO Value ---- -- ----- chid, CHID R channel index -void -(*)(), USRFUNC R the address of a user supplied function -void *, USRARG R An argument copied to the above function +void (*)(struct event_handler_args), + USRFUNC R the address of a user supplied function +const void *, USRARG R An argument copied to the above function ca_real, DELTA R Generate events after +-delta excursions evid * EVIDPTR W An id to refer to this event by */ @@ -638,7 +662,8 @@ unsigned long, chid, /* CHID R channel index */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void *, /* USRARG R An argument copied to the above function*/ +const void *, + /* USRARG R An argument copied to the above function*/ ca_real,/* P_DELTA R Generate events after +delta excursions */ ca_real,/* N_DELTA R Generate events after -delta excursions */ ca_real,/* TIMEOUT R Generate events after timeout sec */ @@ -754,7 +779,8 @@ void epicsShareAPI ca_signal /* Name IO Value */ /* ---- -- ----- */ long, /* CODE R status returned from channel access function */ -char * /* MSG R null term string printed on error */ +const char * + /* MSG R null term string printed on error */ #endif /*CAC_FUNC_PROTO*/ ); @@ -764,8 +790,10 @@ void epicsShareAPI ca_signal_with_file_and_lineno /* Name IO Value */ /* ---- -- ----- */ long, /* CODE R status returned from channel access function */ -char *, /* MSG R null term string printed on error */ -char *, /* FILE R pointer to null terminated file name string */ +const char *, + /* MSG R null term string printed on error */ +const char *, + /* FILE R pointer to null terminated file name string */ int /* LINENO R line number */ #endif /*CAC_FUNC_PROTO*/ ); @@ -785,7 +813,7 @@ int /* LINENO R line number */ __LINE__); \ } -char * epicsShareAPI ca_host_name_function +const char * epicsShareAPI ca_host_name_function ( #ifdef CAC_FUNC_PROTO /* Name IO Value */ @@ -814,7 +842,7 @@ typedef void CAFDHANDLER(); int epicsShareAPI ca_add_fd_registration( #ifdef CAC_FUNC_PROTO CAFDHANDLER *pHandler, -void *pArg +const void *pArg #endif /*CAC_FUNC_PROTO*/ ); @@ -851,12 +879,7 @@ int ca_import_cancel(); * IO operations are initiated then the programmer is free to * block for IO completion within any one of the groups as needed. */ -typedef unsigned WRITEABLE_CA_SYNC_GID; -#ifdef CAC_FUNC_PROTO -typedef const unsigned CA_SYNC_GID; -#else typedef unsigned CA_SYNC_GID; -#endif /* * create a sync group @@ -936,7 +959,8 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void * /* PVALUE R pointer to new channel value of type */ +const void * + /* PVALUE R pointer to new channel value of type */ /* specified. */ #endif /*CAC_FUNC_PROTO*/ ); @@ -957,7 +981,7 @@ int epicsShareAPI ca_sg_stat(); * client user name. */ #ifdef CAC_FUNC_PROTO -int epicsShareAPI ca_modify_user_name(char *pUserName); +int epicsShareAPI ca_modify_user_name(const char *pUserName); #else /*CAC_FUNC_PROTO*/ int epicsShareAPI ca_modify_user_name(); #endif /*CAC_FUNC_PROTO*/ @@ -969,7 +993,7 @@ int epicsShareAPI ca_modify_user_name(); * client host name. */ #ifdef CAC_FUNC_PROTO -int epicsShareAPI ca_modify_host_name(char *pHostName); +int epicsShareAPI ca_modify_host_name(const char *pHostName); #else /*CAC_FUNC_PROTO*/ int epicsShareAPI ca_modify_host_name(); #endif /*CAC_FUNC_PROTO*/ diff --git a/src/ca/caerr.h b/src/ca/caerr.h index 453384534..50469b3f5 100644 --- a/src/ca/caerr.h +++ b/src/ca/caerr.h @@ -154,7 +154,7 @@ HDRVERSIONID(caerrh, "@(#) $Id$") #ifndef CA_ERROR_GLBLSOURCE -epicsShareExtern READONLY char *ca_message_text[]; +epicsShareExtern READONLY char *epicsShareAPI ca_message_text[]; #else READONLY char *ca_message_text[] = diff --git a/src/ca/catime.c b/src/ca/catime.c index 7f0152c53..33abbf5e1 100644 --- a/src/ca/catime.c +++ b/src/ca/catime.c @@ -196,7 +196,9 @@ void timeIt( assert (status == S_ts_OK); #endif TsDiffAsDouble(&delay,&end_time,&start_time); - printf ("Elapsed Per Item = %f\n", delay/(iterations*inlineIter)); + printf ("Elapsed Per Item = %12.8f sec (%10.1f Items per sec)\n", + delay/(iterations*inlineIter), + (iterations*inlineIter)/delay); } diff --git a/src/ca/conn.c b/src/ca/conn.c index 84c316e47..bc5a2bcf3 100644 --- a/src/ca/conn.c +++ b/src/ca/conn.c @@ -30,6 +30,9 @@ /* (dont send all chans in a block) */ /* */ /* $Log$ + * Revision 1.36 1996/09/16 16:35:22 jhill + * local exceptions => exception handler + * * Revision 1.35 1996/06/19 17:59:04 jhill * many 3.13 beta changes * @@ -239,7 +242,7 @@ void manage_conn(int silent) LOCAL void retrySearchRequest (int silent) { ELLLIST channelsSent; - chid chix; + ciu chix; unsigned min_retry_num; unsigned retry_cnt = 0; unsigned retry_cnt_no_handler = 0; @@ -253,7 +256,7 @@ LOCAL void retrySearchRequest (int silent) LOCK; min_retry_num = MAXCONNTRIES; - while (chix = (chid) ellGet (&piiuCast->chidlist)) { + while ( (chix = (ciu) ellGet (&piiuCast->chidlist)) ) { ellAdd (&channelsSent, &chix->node); @@ -359,7 +362,7 @@ LOCAL void logRetryInterval(char *pFN, unsigned lineno) */ void mark_server_available(const struct in_addr *pnet_addr) { - chid chan; + ciu chan; ca_real currentPeriod; bhe *pBHE; unsigned port; @@ -495,10 +498,10 @@ void mark_server_available(const struct in_addr *pnet_addr) * set retry count of all disconnected channels * to zero */ - chan = (chid) ellFirst(&piiuCast->chidlist); + chan = (ciu) ellFirst(&piiuCast->chidlist); while (chan) { chan->retry = 0; - chan = (chid) ellNext (&chan->node); + chan = (ciu) ellNext (&chan->node); } UNLOCK; diff --git a/src/ca/convert.c b/src/ca/convert.c index 944b41eb3..2ef6a7856 100644 --- a/src/ca/convert.c +++ b/src/ca/convert.c @@ -35,6 +35,11 @@ static char *sccsId = "@(#) $Id$"; #include "iocinf.h" #include "net_convert.h" +/* + * NOOP if this isnt required + */ +#ifdef CONVERSION_REQUIRED + /* * if hton is true then it is a host to network conversion * otherwise vise-versa @@ -156,6 +161,9 @@ unsigned long num /* number of values */ char *pSrc = s; char *pDest = d; + /* convert "in place" -> nothing to do */ + if (s == d) + return; if(num == 1){ strcpy(pDest, pSrc); } @@ -212,6 +220,9 @@ unsigned long num /* number of values */ dbr_char_t *pSrc = s; dbr_char_t *pDest = d; + /* convert "in place" -> nothing to do */ + if (s == d) + return; for(i=0; istatus = dbr_ntohs(pSrc->status); pDest->severity = dbr_ntohs(pSrc->severity); + + /* convert "in place" -> nothing else to do */ + if (s == d) + return; + if (num == 1) /* if single value */ strcpy(pDest->value, pSrc->value); else @@ -570,6 +586,10 @@ unsigned long num /* number of values */ pDest->status = dbr_ntohs(pSrc->status); pDest->severity = dbr_ntohs(pSrc->severity); + + if (s == d) /* source == dest -> no more conversions */ + return; + memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); pDest->upper_disp_limit = pSrc->upper_disp_limit; @@ -1686,4 +1706,5 @@ void dbr_htonf (dbr_float_t *IEEEhost, dbr_float_t *IEEEnet) #endif /* IEEE float and little endian */ +#endif /* CONVERSION_REQUIRED */ diff --git a/src/ca/if_depen.c b/src/ca/if_depen.c index 59346ce19..fc0cd8a28 100644 --- a/src/ca/if_depen.c +++ b/src/ca/if_depen.c @@ -40,6 +40,8 @@ static char *sccsId = "@(#) $Id$"; #include "iocinf.h" +#include + /* * Dont use ca_static based lock macros here because this is * also called by the server. All locks required are applied at @@ -79,7 +81,7 @@ int local_addr(int s, struct sockaddr_in *plcladdr) if (status < 0 || ifconf.ifc_len == 0) { ca_printf( "CAC: ioctl failed because \"%s\"\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); ifconf.ifc_len = 0; } @@ -169,12 +171,14 @@ int local_addr (int s, struct sockaddr_in *plcladdr) /* * caDiscoverInterfaces() * - * This routine is provided with the address of an ELLLIST a socket - * and a destination port number. When the routine returns there - * will be one additional inet address (a caAddrNode) in the list - * for each inet interface found that is up and isnt a loop back - * interface. If the interface supports broadcast then I add its - * broadcast address to the list. If the interface is a point to + * This routine is provided with the address of an ELLLIST, a socket + * a destination port number, and a match address. When the + * routine returns there will be one additional inet address + * (a caAddrNode) in the list for each inet interface found that + * is up and isnt a loop back interface (match addr is INADDR_ANY) + * or it matches the specified interface (match addr isnt INADDR_ANY). + * If the interface supports broadcast then I add its broadcast + * address to the list. If the interface is a point to * point link then I add the destination address of the point to * point link to the list. In either case I set the port number * in the address node to the port supplied in the argument @@ -183,7 +187,8 @@ int local_addr (int s, struct sockaddr_in *plcladdr) * LOCK should be applied here for (pList) * (this is also called from the server) */ -void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) +void caDiscoverInterfaces(ELLLIST *pList, int socket, int port, + struct in_addr matchAddr) { struct sockaddr_in localAddr; struct sockaddr_in *pInetAddr; @@ -243,6 +248,7 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) if (status){ continue; } + /* * If its not an internet inteface * then dont use it. @@ -250,9 +256,23 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) if (pifreq->ifr_addr.sa_family != AF_INET) { continue; } + + /* + * save the interface's IP address + */ pInetAddr = (struct sockaddr_in *)&pifreq->ifr_addr; localAddr = *pInetAddr; + /* + * if it isnt a wildcarded interface then look for + * an exact match + */ + if (matchAddr.s_addr != INADDR_ANY) { + if (pInetAddr->sin_addr.s_addr != matchAddr.s_addr) { + continue; + } + } + /* * If this is an interface that supports * broadcast fetch the broadcast address. @@ -285,9 +305,6 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) continue; } - - - pNode = (caAddrNode *) calloc(1,sizeof(*pNode)); if(!pNode){ continue; @@ -306,4 +323,3 @@ void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) free(pIfreqList); } - diff --git a/src/ca/iocinf.c b/src/ca/iocinf.c index 35e018aee..6a098b05a 100644 --- a/src/ca/iocinf.c +++ b/src/ca/iocinf.c @@ -47,6 +47,11 @@ /* address in use so that test works on UNIX */ /* kernels that support multicast */ /* $Log$ + * Revision 1.65 1996/09/16 16:37:02 jhill + * o dont print disconnect message when the last channel on a connection is + * deleted and the conn goes away + * o local exceptions => exception handler + * * Revision 1.64 1996/08/13 23:15:36 jhill * fixed warning * @@ -347,7 +352,7 @@ int net_proto &pNode->destAddr.sa, sizeof(pNode->destAddr.sa)); if(status < 0){ - ca_printf("CAC: no conn err=\"%s\"\n", strerror(MYERRNO)); + ca_printf("CAC: no conn err=\"%s\"\n", strerror(SOCKERRNO)); status = socket_close(sock); if(status<0){ SEVCHK(ECA_INTERNAL,NULL); @@ -405,7 +410,7 @@ int net_proto if(status<0){ free(piiu); ca_printf("CAC: sso (err=\"%s\")\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); status = socket_close(sock); if(status < 0){ SEVCHK(ECA_INTERNAL,NULL); @@ -427,7 +432,7 @@ int net_proto (struct sockaddr *) &saddr, sizeof(saddr)); if(status<0){ - ca_printf("CAC: bind (err=%s)\n",strerror(MYERRNO)); + ca_printf("CAC: bind (err=%s)\n",strerror(SOCKERRNO)); genLocalExcep (ECA_INTERNAL,"bind failed"); } #endif @@ -473,12 +478,12 @@ int net_proto if(status<0){ ca_printf( "Error setting non-blocking io: %s\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } if(fd_register_func){ LOCKEVENTS; - (*fd_register_func)(fd_register_arg, sock, TRUE); + (*fd_register_func)((void *)fd_register_arg, sock, TRUE); UNLOCKEVENTS; } @@ -531,10 +536,13 @@ void caSetupBCastAddrList (ELLLIST *pList, SOCKET sock, unsigned port) * (lock outside because this is used by the server also) */ if (yes) { + struct in_addr addr; + addr.s_addr = INADDR_ANY; caDiscoverInterfaces( pList, sock, - port); + port, + addr); } caAddConfiguredAddr( @@ -629,18 +637,18 @@ void notify_ca_repeater() (struct sockaddr *)&saddr, sizeof(saddr)); if(status < 0){ - if( MYERRNO != EINTR && - MYERRNO != ENOBUFS && - MYERRNO != EWOULDBLOCK && + if( SOCKERRNO != EINTR && + SOCKERRNO != ENOBUFS && + SOCKERRNO != EWOULDBLOCK && /* * This is returned from Linux when * the repeater isnt running */ - MYERRNO != ECONNREFUSED + SOCKERRNO != ECONNREFUSED ){ ca_printf( "CAC: error sending to repeater is \"%s\"\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } } else{ @@ -702,7 +710,7 @@ LOCAL void cac_udp_send_msg_piiu(struct ioc_in_use *piiu) else { int localErrno; - localErrno = MYERRNO; + localErrno = SOCKERRNO; if( localErrno != EWOULDBLOCK && localErrno != ENOBUFS && @@ -789,7 +797,7 @@ LOCAL void cac_tcp_send_msg_piiu(struct ioc_in_use *piiu) return; } - localError = MYERRNO; + localError = SOCKERRNO; if( localError == EWOULDBLOCK || localError == ENOBUFS || @@ -941,16 +949,16 @@ LOCAL void tcp_recv_msg(struct ioc_in_use *piiu) } else if(status <0){ /* try again on status of -1 and no luck this time */ - if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR){ + if(SOCKERRNO == EWOULDBLOCK || SOCKERRNO == EINTR){ break; } - if( MYERRNO != EPIPE && - MYERRNO != ECONNRESET && - MYERRNO != ETIMEDOUT){ + if( SOCKERRNO != EPIPE && + SOCKERRNO != ECONNRESET && + SOCKERRNO != ETIMEDOUT){ ca_printf( "CAC: unexpected recv error (err=%s)\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } TAG_CONN_DOWN(piiu); break; @@ -1063,7 +1071,7 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu) * op would block which is ok to ignore till ready * later */ - if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR){ + if(SOCKERRNO == EWOULDBLOCK || SOCKERRNO == EINTR){ UNLOCK; return; } @@ -1072,12 +1080,12 @@ LOCAL void udp_recv_msg(struct ioc_in_use *piiu) * Avoid spurious ECONNREFUSED bug * in linux */ - if (MYERRNO==ECONNREFUSED) { + if (SOCKERRNO==ECONNREFUSED) { UNLOCK; return; } # endif - ca_printf("Unexpected UDP failure %s\n", strerror(MYERRNO)); + ca_printf("Unexpected UDP failure %s\n", strerror(SOCKERRNO)); } else if(status > 0){ unsigned long bytesActual; @@ -1164,10 +1172,10 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu) pmsglog->nbytes); if(status != OK || piiu->curMsgBytes){ ca_printf( - "%s: bad UDP msg from port=%d addr=%x\n", - __FILE__, - pmsglog->addr.sin_port, - pmsglog->addr.sin_addr.s_addr); + "%s: bad UDP msg from port=%d addr=%s\n", + __FILE__, + ntohs(pmsglog->addr.sin_port), + inet_ntoa(pmsglog->addr.sin_addr)); /* * resync the ring buffer * (discard existing messages) @@ -1207,7 +1215,7 @@ LOCAL void ca_process_udp(struct ioc_in_use *piiu) LOCAL void close_ioc (IIU *piiu) { caAddrNode *pNode; - chid chix; + ciu chix; int status; unsigned chanDisconnectCount; @@ -1231,7 +1239,7 @@ LOCAL void close_ioc (IIU *piiu) chanDisconnectCount = 0u; } else { - chid pNext; + ciu pNext; chanDisconnectCount = ellCount(&piiu->chidlist); @@ -1248,15 +1256,15 @@ LOCAL void close_ioc (IIU *piiu) * handler tries to use a channel before * I mark it disconnected. */ - chix = (chid) ellFirst(&piiu->chidlist); + chix = (ciu) ellFirst(&piiu->chidlist); while (chix) { chix->state = cs_prev_conn; - chix = (chid) ellNext(&chix->node); + chix = (ciu) ellNext(&chix->node); } - chix = (chid) ellFirst(&piiu->chidlist); + chix = (ciu) ellFirst(&piiu->chidlist); while (chix) { - pNext = (chid) ellNext(&chix->node); + pNext = (ciu) ellNext(&chix->node); cacDisconnectChannel(chix, cs_conn); chix = pNext; } @@ -1264,7 +1272,7 @@ LOCAL void close_ioc (IIU *piiu) if (fd_register_func) { LOCKEVENTS; - (*fd_register_func) (fd_register_arg, piiu->sock_chan, FALSE); + (*fd_register_func) ((void *)fd_register_arg, piiu->sock_chan, FALSE); UNLOCKEVENTS; } @@ -1298,7 +1306,7 @@ LOCAL void close_ioc (IIU *piiu) * cacDisconnectChannel() * (LOCK must be applied when calling this routine) */ -void cacDisconnectChannel(chid chix, enum channel_state state) +void cacDisconnectChannel(ciu chix, enum channel_state state) { struct ioc_in_use *piiu; @@ -1412,7 +1420,7 @@ int repeater_installed() (struct sockaddr *) &bd, sizeof bd); if(status<0){ - if(MYERRNO == EADDRINUSE){ + if(SOCKERRNO == EADDRINUSE){ installed = TRUE; } } @@ -1484,12 +1492,12 @@ unsigned long nBytes) */ unsigned long cacRingBufferWrite( struct ca_buffer *pRing, -void *pBuf, +const void *pBuf, unsigned long nBytes) { unsigned long potentialBytes; unsigned long actualBytes; - char *pCharBuf; + const char *pCharBuf; actualBytes = 0; pCharBuf = pBuf; @@ -1787,7 +1795,7 @@ unsigned short caFetchPortConfig(ENV_PARAM *pEnv, unsigned short defaultPort) } /* - * ok to clip to int here because we checked the range + * ok to clip to unsigned short here because we checked the range */ port = (unsigned short) epicsParam; diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index d56551a82..84c5a7b73 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -32,6 +32,9 @@ /************************************************************************/ /* $Log$ + * Revision 1.57 1996/09/16 16:38:05 jhill + * local except => except handler + * * Revision 1.56 1996/08/13 23:16:19 jhill * removed os specific code * @@ -121,28 +124,65 @@ HDRVERSIONID(iocinfh, "$Id$") #include #include -#include +#include "shareLib.h" /* * OS dependent includes */ +#include "osiSock.h" #include "os_depen.h" /* * EPICS includes */ -#include -#include -#include -#include -#include -#include +#include "epicsAssert.h" +#include "cadef.h" +#include "bucketLib.h" +#include "ellLib.h" +#include "envDefs.h" +#include "epicsPrint.h" /* * CA private includes */ #include "addrList.h" #include "caProto.h" +#include "net_convert.h" + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef OK +#define OK 0 +#endif + +#ifndef ERROR +#define ERROR (-1) +#endif + +#ifndef NELEMENTS +#define NELEMENTS(array) (sizeof(array)/sizeof((array)[0])) +#endif + +#ifndef LOCAL +#define LOCAL static +#endif + +/* + * writable channel_in_use and pending_event pointers + * for internal use + */ +typedef struct channel_in_use *ciu; +typedef struct pending_event *miu; #ifndef min #define min(A,B) ((A)>(B)?(B):(A)) @@ -173,7 +213,7 @@ if(!ca_static){ \ #define VALID_MSG(PIIU) (piiu->read_seq == piiu->cur_read_seq) #define SETPENDRECV {pndrecvcnt++;} -#define CLRPENDRECV(LOCK) {if(--pndrecvcnt<1){POST_IO_EV;}} +#define CLRPENDRECV {if(--pndrecvcnt<1){POST_IO_EV;}} struct udpmsglog{ long nbytes; @@ -295,7 +335,7 @@ typedef struct caclient_put_notify{ #define nextFastBucketId (ca_static->ca_nextFastBucketId) #if defined(vxWorks) -# define io_done_sem (ca_static->ca_io_done_sem) +# define io_done_sem (ca_static->ca_io_done_sem) # define evuser (ca_static->ca_evuser) # define client_lock (ca_static->ca_client_lock) # define event_lock (ca_static->ca_event_lock) @@ -438,16 +478,11 @@ struct ca_static{ IIU *ca_piiuCast; void (*ca_exception_func) (struct exception_handler_args); - void *ca_exception_arg; -#if 0 - void (*ca_connection_func) - (struct connection_handler_args); - void *ca_connection_arg; -#endif + const void *ca_exception_arg; int (*ca_printf_func)(const char *pformat, va_list args); void (*ca_fd_register_func) (void *, SOCKET, int); - void *ca_fd_register_arg; + const void *ca_fd_register_arg; char *ca_pUserName; char *ca_pHostName; BUCKET *ca_pSlowBucket; @@ -490,11 +525,11 @@ struct ca_static{ * one per outstanding op */ typedef struct{ - ELLNODE node; - WRITEABLE_CA_SYNC_GID id; - void *pValue; - unsigned long magic; - unsigned long seqNo; + ELLNODE node; + CA_SYNC_GID id; + void *pValue; + unsigned long magic; + unsigned long seqNo; }CASGOP; @@ -503,7 +538,7 @@ typedef struct{ */ typedef struct{ ELLNODE node; - WRITEABLE_CA_SYNC_GID id; + CA_SYNC_GID id; unsigned long magic; unsigned long opPendCount; unsigned long seqNo; @@ -532,7 +567,7 @@ struct ca_static *ca_static; void cac_send_msg(void); void cac_mux_io(struct timeval *ptimeout); int repeater_installed(void); -int search_msg(chid chix, int reply_type); +int search_msg(ciu chix, int reply_type); int ca_request_event(evid monix); void ca_busy_message(struct ioc_in_use *piiu); void ca_ready_message(struct ioc_in_use *piiu); @@ -570,7 +605,7 @@ int alloc_ioc( ); unsigned long cacRingBufferWrite( struct ca_buffer *pRing, - void *pBuf, + const void *pBuf, unsigned long nBytes); unsigned long cacRingBufferRead( @@ -625,16 +660,15 @@ int cac_os_depen_init(struct ca_static *pcas); void cac_os_depen_exit (struct ca_static *pcas); void ca_process_exit(); void ca_spawn_repeater(void); -typedef void CACVRTFUNC(void *pSrc, void *pDest, int hton, unsigned long count); void cac_gettimeval(struct timeval *pt); /* returns A - B in floating secs */ ca_real cac_time_diff(ca_time *pTVA, ca_time *pTVB); /* returns A + B in integer secs & integer usec */ ca_time cac_time_sum(ca_time *pTVA, ca_time *pTVB); -void caIOBlockFree(evid pIOBlock); +void caIOBlockFree(miu pIOBlock); void clearChannelResources(unsigned id); void caSetDefaultPrintfHandler (void); -void cacDisconnectChannel(chid chix, enum channel_state state); +void cacDisconnectChannel(ciu chix, enum channel_state state); int caSendMsgPending(void); void generateLocalExceptionWithFileAndLine(long stat, char *ctx, char *pFile, unsigned line); diff --git a/src/ca/iocmsg.h b/src/ca/iocmsg.h deleted file mode 100644 index 5a156d8e6..000000000 --- a/src/ca/iocmsg.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef __IOCMSG__ -/* $Id$ */ -/* - * History - * .01 01xx90 joh removed status field in favor of a independent m_cmmd- - * saves space on every successful operation - * - * .02 041390 joh moved server ports to above IPPORT_USERRESERVED - * see in.h - * - * .03 060391 joh Bumped protocol version to 4 to support changes for - * SPARC alignment in db_access.h - * - * .04 071291 joh New command added - claim channel in use block - * - * .05 011294 joh New command added - write notify - * - * .06 020194 joh New command added for CA V4.1 - client name - * - * .07 041194 joh New command added for CA V4.2 - access rights - * - * .08 050594 joh New command added for CA V4.3 - echo request - * - * .09 050594 joh New command added for CA V4.3 - repeater fanout register - * - * .10 050594 joh New command added for CA V4.3 - wakeup the server - * $Log$ - * Revision 1.23 1995/08/23 00:35:17 jhill - * added log entries - * - */ - -#define __IOCMSG__ - -HDRVERSIONID(iocmsgh, "@(#) $Id$ CA version 4.4") - -/* TCP/UDP port number (bumped each protocol change) */ -#define CA_PROTOCOL_VERSION 4 -#define CA_MINOR_VERSION 6 -#define CA_UKN_MINOR_VERSION 0 /* unknown minor version */ -#if CA_PROTOCOL_VERSION == 4 -#define CA_V41(MAJOR,MINOR) ((MINOR)>=1) -#define CA_V42(MAJOR,MINOR) ((MINOR)>=2) -#define CA_V43(MAJOR,MINOR) ((MINOR)>=3) -#define CA_V44(MAJOR,MINOR) ((MINOR)>=4) -#define CA_V45(MAJOR,MINOR) ((MINOR)>=5) -#define CA_V46(MAJOR,MINOR) ((MINOR)>=6) -#elif CA_PROTOCOL_VERSION > 4 -#define CA_V41(MAJOR,MINOR) ( 1 ) -#define CA_V42(MAJOR,MINOR) ( 1 ) -#define CA_V43(MAJOR,MINOR) ( 1 ) -#define CA_V44(MAJOR,MINOR) ( 1 ) -#define CA_V45(MAJOR,MINOR) ( 1 ) -#define CA_V46(MAJOR,MINOR) ( 1 ) -#else -#define CA_V41(MAJOR,MINOR) ( 0 ) -#define CA_V42(MAJOR,MINOR) ( 0 ) -#define CA_V43(MAJOR,MINOR) ( 0 ) -#define CA_V44(MAJOR,MINOR) ( 0 ) -#define CA_V45(MAJOR,MINOR) ( 0 ) -#define CA_V46(MAJOR,MINOR) ( 0 ) -#endif - -/* - * NOTE: These port numbers are only used if the CA repeater and - * CA server port numbers cant be obtained from the EPICS - * environment variables "EPICS_CA_REPEATER_PORT" and - * "EPICS_CA_SERVER_PORT" - */ -#define CA_PORT_BASE IPPORT_USERRESERVED + 56U -#define CA_SERVER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2) -#define CA_REPEATER_PORT (CA_PORT_BASE+CA_PROTOCOL_VERSION*2+1) - -#define MAX_UDP 1024 -#define MAX_TCP (MAX_UDP*16) /* so waveforms fit */ -#define MAX_MSG_SIZE (MAX_TCP) /* the larger of tcp and udp max */ - -/* - * architecture independent types - * - * (so far this works on all archs we have ported to) - */ -typedef unsigned short ca_uint16_t; -typedef unsigned int ca_uint32_t; -typedef float ca_float32_t; -typedef ca_uint32_t caResId; - - /* values for m_cmmd */ -#define IOC_NOOP 0 /* do nothing, but verify TCP */ -#define IOC_EVENT_ADD 1 /* add an event */ -#define IOC_EVENT_CANCEL 2 /* cancel an event */ -#define IOC_READ 3 /* read and return a channel value*/ -#define IOC_WRITE 4 /* write a channel value */ -#define IOC_SNAPSHOT 5 /* snapshot of the system */ -#define IOC_SEARCH 6 /* IOC channel search */ -#define IOC_BUILD 7 /* build - obsolete */ -#define IOC_EVENTS_OFF 8 /* flow control */ -#define IOC_EVENTS_ON 9 /* flow control */ -#define IOC_READ_SYNC 10 /* purge old reads */ -#define IOC_ERROR 11 /* an operation failed */ -#define IOC_CLEAR_CHANNEL 12 /* free chan resources */ -#define IOC_RSRV_IS_UP 13 /* CA server has joined the net */ -#define IOC_NOT_FOUND 14 /* channel not found */ -#define IOC_READ_NOTIFY 15 /* add a one shot event */ -#define IOC_READ_BUILD 16 /* read and build - obsolete */ -#define REPEATER_CONFIRM 17 /* registration confirmation */ -#define IOC_CLAIM_CIU 18 /* client claims resource in server */ -#define IOC_WRITE_NOTIFY 19 /* notify after write chan value */ -#define IOC_CLIENT_NAME 20 /* CA V4.1 identify client */ -#define IOC_HOST_NAME 21 /* CA V4.1 identify client */ -#define IOC_ACCESS_RIGHTS 22 /* CA V4.2 asynch access rights chg */ -#define IOC_ECHO 23 /* CA V4.3 connection verify */ -#define REPEATER_REGISTER 24 /* registr for repeater fan out */ -#define IOC_SIGNAL 25 /* knock the server out of select */ -#define IOC_CLAIM_CIU_FAILED 26 /* unable to create chan resource in server */ - -/* - * for use with search and not_found (if search fails and - * its not a broadcast tell the client to look elesewhere) - */ -#define DOREPLY 10 -#define DONTREPLY 5 - -/* size of object in bytes rounded up to nearest oct word */ -#define OCT_ROUND(A) ((((unsigned long)(A))+7)>>3) -#define OCT_SIZEOF(A) (OCT_ROUND(sizeof(A))) - -/* size of object in bytes rounded up to nearest long word */ -#define QUAD_ROUND(A) (((unsigned long)(A))+3)>>2) -#define QUAD_SIZEOF(A) (QUAD_ROUND(sizeof(A))) - -/* size of object in bytes rounded up to nearest short word */ -#define BI_ROUND(A) ((((unsigned long)(A))+1)>>1) -#define BI_SIZEOF(A) (BI_ROUND(sizeof(A))) - -/* - * For communicating access rights to the clients - * - * (placed in m_available hdr field of IOC_ACCESS_RIGHTS cmmd - */ -#define CA_ACCESS_RIGHT_READ (1<<0) -#define CA_ACCESS_RIGHT_WRITE (1<<1) - -/* - * All structures passed in the protocol must have individual - * fields aligned on natural boundaries. - * - * NOTE: all structures declared in this file must have a - * byte count which is evenly divisible by 8 matching - * the largest atomic data type in db_access.h. - */ -#define CA_MESSAGE_ALIGN(A) (OCT_ROUND(A)<<3) - -/* - * the common part of each message sent/recv by the - * CA server. - */ -typedef struct extmsg { - ca_uint16_t m_cmmd; /* operation to be performed */ - ca_uint16_t m_postsize; /* size of message extension */ - ca_uint16_t m_type; /* operation data type */ - ca_uint16_t m_count; /* operation data count */ - ca_uint32_t m_cid; /* channel identifier */ - ca_uint32_t m_available; /* undefined message location for use - * by client processes */ -}caHdr; - -/* - * for monitor (event) message extension - */ -struct mon_info{ - ca_float32_t m_lval; /* low delta */ - ca_float32_t m_hval; /* high delta */ - ca_float32_t m_toval; /* period btween samples */ - ca_uint16_t m_mask; /* event select mask */ - ca_uint16_t m_pad; /* extend to 32 bits */ -}; - -struct monops { /* monitor req opi to ioc */ - struct extmsg m_header; - struct mon_info m_info; -}; - -#endif /* __IOCMSG__ */ - diff --git a/src/ca/net_convert.h b/src/ca/net_convert.h index 1a659de3e..ab6da28b0 100644 --- a/src/ca/net_convert.h +++ b/src/ca/net_convert.h @@ -1,10 +1,18 @@ /* * $Id$ * - * N E T _ C O N V E R T . H * MACROS for rapid conversion between HOST data formats and those used * by the IOCs (NETWORK). * + * Author: J. Hill + * + * The conversion routines are used in both ca lib + * and the IOC ca server (base/rsrv). + * The latter, however, cannot include os_depen.h so + * I extracted the conversion specific code from there + * and put it in this "now stand alone" net_convert.h + * 8-22-96 -kuk- + * * * joh 09-13-90 force MIT sign to zero if exponent is zero * to prevent a reseved operand fault. @@ -16,8 +24,79 @@ * */ +#ifndef _NET_CONVERT_H +#define _NET_CONVERT_H + #include +/* + * Here are the definitions for architecture dependent byte ordering + * and floating point format + */ +#if defined(VAX) +# define CA_FLOAT_MIT +# define CA_LITTLE_ENDIAN +#elif defined(_X86_) +# define CA_FLOAT_IEEE +# define CA_LITTLE_ENDIAN +#elif (defined(__ALPHA) && defined(VMS) || defined(__alpha)) && defined(VMS) +# define CA_FLOAT_MIT +# define CA_LITTLE_ENDIAN +#elif (defined(__ALPHA) && defined(UNIX) || defined(__alpha)) && defined(UNIX) +# define CA_FLOAT_IEEE +# define CA_LITTLE_ENDIAN +#else +# define CA_FLOAT_IEEE +# define CA_BIG_ENDIAN +#endif + +/* + * some architecture sanity checks + */ +#if defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) +#error defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) +#endif +#if !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) +#error !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) +#endif +#if defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) +#error defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) +#endif +#if !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) +#error !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) +#endif + +/* + * CONVERSION_REQUIRED is set if either the byte order + * or the floating point does not match + */ +#if !defined(CA_FLOAT_IEEE) || !defined(CA_BIG_ENDIAN) +#define CONVERSION_REQUIRED +#endif + +/* + * if hton is true then it is a host to network conversion + * otherwise vise-versa + * + * net format: big endian and IEEE float + */ + +typedef void CACVRTFUNC(void *pSrc, void *pDest, int hton, unsigned long count); + +#ifdef CONVERSION_REQUIRED +/* cvrt is (array of) (pointer to) (function returning) int */ +extern CACVRTFUNC *cac_dbr_cvrt[]; +#endif + + +/* + * Macros ... + * + * This is also used in the ca server on pc486 archs, + * where source and destination buffers are identical, + * so we need a tmp variable in e.g. 'double' conversions. + */ + #ifdef CA_LITTLE_ENDIAN # ifndef ntohs # define ntohs(SHORT)\ @@ -79,12 +158,20 @@ {*((dbr_long_t *)(HOST)) = ntohl(*((dbr_long_t *)(NET )));} # define dbr_htonf(HOST,NET) \ {*((dbr_long_t *)(NET) ) = htonl(*((dbr_long_t *)(HOST)));} -# define dbr_ntohd(NET,HOST) \ - { ((dbr_long_t *)(HOST))[1] = ntohl(((dbr_long_t *)(NET))[0]) ; \ - ((dbr_long_t *)(HOST))[0] = ntohl(((dbr_long_t *)(NET))[1]) ;} -# define dbr_htond(HOST,NET) \ - { ((dbr_long_t *)(NET))[1] = htonl(((dbr_long_t *)(HOST))[0]) ; \ - ((dbr_long_t *)(NET))[0] = htonl(((dbr_long_t *)(HOST))[1]) ;} +# define dbr_ntohd(NET,HOST) \ + { \ + dbr_long_t cvrt_tmp; \ + cvrt_tmp = ntohl(((dbr_long_t *)(NET))[0]); \ + ((dbr_long_t *)(HOST))[0] = ntohl(((dbr_long_t *)(NET))[1]); \ + ((dbr_long_t *)(HOST))[1] = cvrt_tmp; \ + } +# define dbr_htond(HOST,NET) \ + { \ + dbr_long_t cvrt_tmp; \ + cvrt_tmp = htonl(((dbr_long_t *)(HOST))[0]); \ + ((dbr_long_t *)(NET))[0] = htonl(((dbr_long_t *)(HOST))[1]); \ + ((dbr_long_t *)(NET))[1] = cvrt_tmp; \ + } #else void dbr_htond(dbr_double_t *pHost, dbr_double_t *pNet); void dbr_ntohd(dbr_double_t *pNet, dbr_double_t *pHost); @@ -92,3 +179,4 @@ void dbr_ntohf(dbr_float_t *pNet, dbr_float_t *pHost); #endif +#endif /* define _NET_CONVERT_H */ diff --git a/src/ca/os_depen.h b/src/ca/os_depen.h index 5595a779a..3852b6eb2 100644 --- a/src/ca/os_depen.h +++ b/src/ca/os_depen.h @@ -42,45 +42,19 @@ static char *os_depenhSccsId = "$Id$"; * each socket library */ #ifdef UNIX -# include # include # include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - /* - * normally these are included by ioctl.h - */ -# ifdef SOLARIS -# include -# include -# endif # define CA_OS_CONFIGURED #endif #ifdef vxWorks # include # include -# include -# include -# include -# include -# include -# include -# include # include # include # include # include -# include # include # include # include @@ -90,28 +64,16 @@ static char *os_depenhSccsId = "$Id$"; # include # include # include +# include # include # include -# include -/* - * logistical problems prevent including this file - */ -#if 0 -#define caClient -#include -#endif # define CA_OS_CONFIGURED #endif #ifdef VMS -# include -# include -# include -# include #if !defined(UCX) -# include # include #else # include @@ -137,8 +99,6 @@ static char *os_depenhSccsId = "$Id$"; #ifdef WIN32 # include # include -# include -# include # define CA_OS_CONFIGURED #endif /*WIN32*/ @@ -146,87 +106,8 @@ static char *os_depenhSccsId = "$Id$"; #error Please define one of vxWorks, UNIX, VMS, or WIN32 #endif -/* - * Here are the definitions for architecture dependent byte ordering - * and floating point format - */ -#if defined(VAX) -# define CA_FLOAT_MIT -# define CA_LITTLE_ENDIAN -#elif defined(_X86_) -# define CA_FLOAT_IEEE -# define CA_LITTLE_ENDIAN -#elif (defined(__ALPHA) && defined(VMS) || defined(__alpha)) && defined(VMS) -# define CA_FLOAT_MIT -# define CA_LITTLE_ENDIAN -#elif (defined(__ALPHA) && defined(UNIX) || defined(__alpha)) && defined(UNIX) -# define CA_FLOAT_IEEE -# define CA_LITTLE_ENDIAN -#else -# define CA_FLOAT_IEEE -# define CA_BIG_ENDIAN -#endif - -/* - * some architecture sanity checks - */ -#if defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) -#error defined(CA_BIG_ENDIAN) && defined(CA_LITTLE_ENDIAN) -#endif -#if !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) -#error !defined(CA_BIG_ENDIAN) && !defined(CA_LITTLE_ENDIAN) -#endif -#if defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) -#error defined(CA_FLOAT_IEEE) && defined(CA_FLOAT_MIT) -#endif -#if !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) -#error !defined(CA_FLOAT_IEEE) && !defined(CA_FLOAT_MIT) -#endif - -/* - * CONVERSION_REQUIRED is set if either the byte order - * or the floating point does not match - */ -#if !defined(CA_FLOAT_IEEE) || !defined(CA_BIG_ENDIAN) -#define CONVERSION_REQUIRED -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef OK -#define OK 0 -#endif - -#ifndef ERROR -#define ERROR (-1) -#endif - -#ifndef NELEMENTS -#define NELEMENTS(array) (sizeof(array)/sizeof((array)[0])) -#endif - -#ifndef LOCAL -#define LOCAL static -#endif - -/* - * BSD prototypes missing from SUNOS4, MULTINET and - * perhaps other environments - */ -#include -#include - #if defined(vxWorks) +# define POST_IO_EV semGive(io_done_sem) # define VXTASKIDNONE 0 # define LOCK semTake(client_lock, WAIT_FOREVER); # define UNLOCK semGive(client_lock); @@ -238,79 +119,34 @@ static char *os_depenhSccsId = "$Id$"; (((int)taskIdCurrent)==event_tid || ca_static->recv_tid == (int)taskIdCurrent) # define VXTHISTASKID taskIdSelf() # define abort() taskSuspend(VXTHISTASKID) -# define socket_close(S) close(S) - /* vxWorks still has a brain dead func proto for ioctl */ -# define socket_ioctl(A,B,C) ioctl(A,B,(int)C) -# define MYERRNO (errnoGet()&0xffff) -# define POST_IO_EV semGive(io_done_sem) - typedef int SOCKET; -# define INVALID_SOCKET (-1) #endif #if defined(UNIX) +# define POST_IO_EV # define LOCK # define UNLOCK # define LOCKEVENTS # define UNLOCKEVENTS # define EVENTLOCKTEST (post_msg_active) -# define socket_close(S) close(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -# define MYERRNO errno -# define POST_IO_EV - typedef int SOCKET; -# define INVALID_SOCKET (-1) #endif #if defined(VMS) -# if defined(WINTCP) /* Wallangong */ - /* (the VAXC runtime lib has its own close */ -# define socket_close(S) netclose(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -# endif -# if defined(UCX) /* GeG 09-DEC-1992 */ -# define socket_close(S) close(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -# endif -# ifdef WINTCP - extern int uerrno; -# define MYERRNO uerrno -# else -# ifdef UCX -# define MYERRNO errno -# else -# define MYERRNO socket_errno -# endif -# endif # define POST_IO_EV # define LOCK # define UNLOCK # define LOCKEVENTS # define UNLOCKEVENTS # define EVENTLOCKTEST (post_msg_active) - typedef int SOCKET; -# define INVALID_SOCKET (-1) #endif #ifdef WIN32 +# define POST_IO_EV # define LOCK # define UNLOCK # define LOCKEVENTS # define UNLOCKEVENTS -# define EVENTLOCKTEST (post_msg_active) -# define MAXHOSTNAMELEN 75 -# define IPPORT_USERRESERVED 5000U -# define EWOULDBLOCK WSAEWOULDBLOCK -# define ENOBUFS WSAENOBUFS -# define ECONNRESET WSAECONNRESET -# define ETIMEDOUT WSAETIMEDOUT -# define EADDRINUSE WSAEADDRINUSE -# define ECONNREFUSED WSAECONNREFUSED -# define socket_close(S) closesocket(S) -# define socket_ioctl(A,B,C) ioctlsocket(A,B,C) -# define MYERRNO WSAGetLastError() -# define POST_IO_EV +# define EVENTLOCKTEST (post_msg_active) #endif /*WIN32*/ - -#endif +#endif /* INCos_depenh */ diff --git a/src/ca/posix_depen.c b/src/ca/posix_depen.c index 2a4edf024..295c66f10 100644 --- a/src/ca/posix_depen.c +++ b/src/ca/posix_depen.c @@ -29,6 +29,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.19 1996/07/09 22:41:02 jhill + * pass nill 2nd arg to gettimeofday() + * * Revision 1.18 1996/06/20 21:19:29 jhill * fixed posix signal problem with "cc -Xc" * @@ -46,7 +49,6 @@ #include #include -#include #include "iocinf.h" @@ -141,7 +143,7 @@ int cac_os_depen_init(struct ca_static *pcas) ca_printf( "%s: Error from signal replace was \"%s\"\n", __FILE__, - strerror(MYERRNO)); + strerror(errno)); } } } @@ -149,7 +151,7 @@ int cac_os_depen_init(struct ca_static *pcas) ca_printf( "%s: Error from signal query was \"%s\"\n", __FILE__, - strerror(MYERRNO)); + strerror(errno)); } status = ca_os_independent_init (); @@ -238,7 +240,7 @@ void ca_spawn_repeater() if(status<0){ ca_printf("!!WARNING!!\n"); ca_printf("The executable \"%s\" couldnt be located\n", pImageName); - ca_printf("because of errno = \"%s\"\n", strerror(MYERRNO)); + ca_printf("because of errno = \"%s\"\n", strerror(errno)); ca_printf("You may need to modify your PATH environment variable.\n"); ca_printf("Creating CA repeater with fork() system call.\n"); ca_printf("Repeater will inherit parents process name and resources.\n"); diff --git a/src/ca/repeater.c b/src/ca/repeater.c index b4f696c33..b1a6bc8ed 100644 --- a/src/ca/repeater.c +++ b/src/ca/repeater.c @@ -63,6 +63,9 @@ * datagram socket (and watching for ECONNREFUSED) * * $Log$ + * Revision 1.37 1996/09/04 20:02:32 jhill + * fixed gcc warning + * * Revision 1.36 1996/07/12 00:40:48 jhill * fixed client disconnect problem under solaris * @@ -137,12 +140,12 @@ void ca_repeater() /* * test for server was already started */ - if (MYERRNO==EADDRINUSE) { + if (SOCKERRNO==EADDRINUSE) { exit(0); } ca_printf("%s: Unable to create repeater socket because \"%s\"\n", __FILE__, - strerror(MYERRNO)); + strerror(SOCKERRNO)); exit(0); } @@ -174,12 +177,12 @@ void ca_repeater() * Avoid spurious ECONNREFUSED bug * in linux */ - if (MYERRNO==ECONNREFUSED) { + if (SOCKERRNO==ECONNREFUSED) { continue; } # endif ca_printf("CA Repeater: recv err %s\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); continue; } @@ -246,10 +249,10 @@ LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize) #endif } if(status < 0){ - if (MYERRNO == ECONNREFUSED) { + if (SOCKERRNO == ECONNREFUSED) { #ifdef DEBUG ca_printf("Deleted client %d\n", - pclient->from.sin_port); + ntohs( pclient->from.sin_port)); #endif ellDelete(&theClients, &pclient->node); @@ -259,7 +262,7 @@ LOCAL void fanOut(struct sockaddr_in *pFrom, const char *pMsg, unsigned msgSize) else { ca_printf( "CA Repeater: fan out err was \"%s\"\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } } } @@ -282,10 +285,10 @@ LOCAL void verifyClients() ellAdd(&theClients, &pclient->node); sock = makeSocket(ntohs(pclient->from.sin_port), FALSE); - if (sock>=0) { + if (sock!=INVALID_SOCKET) { #ifdef DEBUG ca_printf("Deleted client %d\n", - pclient->from.sin_port); + ntohs(pclient->from.sin_port)); #endif ellDelete(&theClients, &pclient->node); socket_close(sock); @@ -293,9 +296,9 @@ LOCAL void verifyClients() free(pclient); } else { - if (MYERRNO!=EADDRINUSE) { + if (SOCKERRNO!=EADDRINUSE) { ca_printf( - "CA Repeater: bind test err was \"%s\"\n", strerror(MYERRNO)); + "CA Repeater: bind test err was \"%s\"\n", strerror(SOCKERRNO)); } } } @@ -324,6 +327,16 @@ LOCAL SOCKET makeSocket(unsigned short port, int reuseAddr) * no need to bind if unconstrained */ if (port != PORT_ANY) { + + memset((char *)&bd, 0, sizeof(bd)); + bd.sin_family = AF_INET; + bd.sin_addr.s_addr = INADDR_ANY; + bd.sin_port = htons(port); + status = bind(sock, (struct sockaddr *)&bd, (int)sizeof(bd)); + if (status<0) { + socket_close(sock); + return INVALID_SOCKET; + } if (reuseAddr) { status = setsockopt( sock, SOL_SOCKET, @@ -333,19 +346,9 @@ LOCAL SOCKET makeSocket(unsigned short port, int reuseAddr) if (status<0) { ca_printf( "%s: set socket option failed because \"%s\"\n", - __FILE__, strerror(MYERRNO)); + __FILE__, strerror(SOCKERRNO)); } } - - memset((char *)&bd, 0, sizeof(bd)); - bd.sin_family = AF_INET; - bd.sin_addr.s_addr = INADDR_ANY; - bd.sin_port = htons(port); - status = bind(sock, (struct sockaddr *)&bd, (int)sizeof(bd)); - if(status<0){ - socket_close(sock); - return INVALID_SOCKET; - } } return sock; @@ -398,7 +401,7 @@ struct sockaddr_in *pFrom) free(pclient); ca_printf("%s: no client sock because \"%s\"\n", __FILE__, - strerror(MYERRNO)); + strerror(SOCKERRNO)); return; } @@ -421,7 +424,7 @@ struct sockaddr_in *pFrom) #ifdef DEBUG ca_printf ( "Added %d\n", - pFrom->sin_port); + ntohs(pFrom->sin_port)); #endif } @@ -436,7 +439,7 @@ struct sockaddr_in *pFrom) if (status >= 0) { assert(status == sizeof(confirm)); } - else if (MYERRNO == ECONNREFUSED){ + else if (SOCKERRNO == ECONNREFUSED){ #ifdef DEBUG ca_printf("Deleted repeater client=%d sending ack\n", pFrom->sin_port); @@ -447,7 +450,7 @@ struct sockaddr_in *pFrom) } else { ca_printf("CA Repeater: confirm err was \"%s\"\n", - strerror(MYERRNO)); + strerror(SOCKERRNO)); } /* diff --git a/src/ca/service.c b/src/ca/service.c index cd9ea386f..486a8eb40 100644 --- a/src/ca/service.c +++ b/src/ca/service.c @@ -76,7 +76,7 @@ static char *sccsId = "@(#) $Id$"; LOCAL void reconnect_channel( IIU *piiu, -chid chan +ciu chan ); LOCAL int cacMsg( @@ -177,17 +177,25 @@ unsigned long blockSize * make sure we have a large enough message body cache */ if (piiu->curMsg.m_postsize>piiu->curDataMax) { + void *pCurData; + size_t size; + + /* + * scalar DBR_STRING is sometimes clipped to the + * actual string size so make sure this cache is + * as large as one DBR_STRING so they will + * not page fault if they read MAX_STRING_SIZE + * bytes (instead of the actual string size). + */ + size = max(piiu->curMsg.m_postsize,MAX_STRING_SIZE); + pCurData = (void *) calloc(1u, size); + if(!pCurData){ + return ERROR; + } if(piiu->pCurData){ free(piiu->pCurData); } - piiu->pCurData = (void *) - malloc(piiu->curMsg.m_postsize); - if(!piiu->pCurData){ - piiu->curDataMax = 0; - piiu->curMsgBytes = 0; - piiu->curDataBytes = 0; - return ERROR; - } + piiu->pCurData = pCurData; piiu->curDataMax = piiu->curMsg.m_postsize; } @@ -241,7 +249,8 @@ struct ioc_in_use *piiu, const struct in_addr *pnet_addr ) { - evid monix; + miu monix; + ciu pChan; switch (piiu->curMsg.m_cmmd) { @@ -260,7 +269,7 @@ const struct in_addr *pnet_addr * run the user's event handler */ LOCK; - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &piiu->curMsg.m_available); UNLOCK; @@ -274,7 +283,7 @@ const struct in_addr *pnet_addr * chid in the interim */ if (monix->usr_func) { - args.usr = monix->usr_arg; + args.usr = (void *) monix->usr_arg; args.chid = monix->chan; args.type = monix->type; args.count = monix->count; @@ -308,7 +317,7 @@ const struct in_addr *pnet_addr */ LOCK; - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &piiu->curMsg.m_available); UNLOCK; @@ -337,7 +346,7 @@ const struct in_addr *pnet_addr piiu->curMsg.m_count); # endif - args.usr = monix->usr_arg; + args.usr = (void *) monix->usr_arg; args.chid = monix->chan; args.type = piiu->curMsg.m_type; args.count = piiu->curMsg.m_count; @@ -377,7 +386,7 @@ const struct in_addr *pnet_addr * run the user's event handler */ LOCK; - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &piiu->curMsg.m_available); UNLOCK; @@ -392,7 +401,8 @@ const struct in_addr *pnet_addr */ if (!piiu->curMsg.m_postsize) { LOCK; - ellDelete(&monix->chan->eventq, &monix->node); + pChan = (ciu) monix->chan; /* discard const */ + ellDelete(&pChan->eventq, &monix->node); caIOBlockFree(monix); UNLOCK; @@ -421,7 +431,7 @@ const struct in_addr *pnet_addr * structure rather than the structure itself * early on. */ - args.usr = monix->usr_arg; + args.usr = (void *) monix->usr_arg; args.chid = monix->chan; args.type = piiu->curMsg.m_type; args.count = piiu->curMsg.m_count; @@ -450,13 +460,13 @@ const struct in_addr *pnet_addr } case CA_PROTO_READ: { - evid pIOBlock; + miu pIOBlock; /* * verify the event id */ LOCK; - pIOBlock = (evid) bucketLookupItemUnsignedId( + pIOBlock = (miu) bucketLookupItemUnsignedId( pFastBucket, &piiu->curMsg.m_available); UNLOCK; @@ -476,7 +486,7 @@ const struct in_addr *pnet_addr # ifdef CONVERSION_REQUIRED (*cac_dbr_cvrt[piiu->curMsg.m_type])( piiu->pCurData, - pIOBlock->usr_arg, + (void *) pIOBlock->usr_arg, FALSE, piiu->curMsg.m_count); # else @@ -499,7 +509,7 @@ const struct in_addr *pnet_addr /* * decrement the outstanding IO count */ - CLRPENDRECV(TRUE); + CLRPENDRECV; } LOCK; ellDelete(&pend_read_list, &pIOBlock->node); @@ -520,7 +530,20 @@ const struct in_addr *pnet_addr { struct in_addr ina; - ina.s_addr = piiu->curMsg.m_available; + /* + * this allows a fan-out server to potentially + * insert the true address of a server + * (servers prior to 3.13 always set this + * field to one of the ip addresses of the host) + * (clients prior to 3.13 always expect that this + * field is set to the server's IP address). + */ + if (piiu->curMsg.m_available != INADDR_ANY) { + ina.s_addr = piiu->curMsg.m_available; + } + else { + ina = *pnet_addr; + } mark_server_available(&ina); } UNLOCK; @@ -543,10 +566,10 @@ const struct in_addr *pnet_addr case CA_PROTO_ERROR: { ELLLIST *pList = NULL; - evid monix; + miu monix; char nameBuf[64]; char context[255]; - caHdr *req = piiu->pCurData; + caHdr *req = piiu->pCurData; int op; struct exception_handler_args args; @@ -584,24 +607,24 @@ const struct in_addr *pnet_addr LOCK; switch (ntohs(req->m_cmmd)) { case CA_PROTO_READ_NOTIFY: - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &req->m_available); pList = &pend_read_list; op = CA_OP_GET; break; case CA_PROTO_READ: - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &req->m_available); if(monix){ - args.addr = monix->usr_arg; + args.addr = (void *) monix->usr_arg; } pList = &pend_read_list; op = CA_OP_GET; break; case CA_PROTO_WRITE_NOTIFY: - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &req->m_available); pList = &pend_write_list; @@ -614,16 +637,17 @@ const struct in_addr *pnet_addr op = CA_OP_SEARCH; break; case CA_PROTO_EVENT_ADD: - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &req->m_available); op = CA_OP_ADD_EVENT; if (monix) { - pList = &monix->chan->eventq; + ciu pChan = (ciu) monix->chan; + pList = &pChan->eventq; } break; case CA_PROTO_EVENT_CANCEL: - monix = (evid) bucketLookupItemUnsignedId( + monix = (miu) bucketLookupItemUnsignedId( pFastBucket, &req->m_available); op = CA_OP_CLEAR_EVENT; @@ -643,7 +667,7 @@ const struct in_addr *pnet_addr args.chid = bucketLookupItemUnsignedId (pSlowBucket, &piiu->curMsg.m_cid); UNLOCK; - args.usr = ca_static->ca_exception_arg; + args.usr = (void *) ca_static->ca_exception_arg; args.type = ntohs (req->m_type); args.count = ntohs (req->m_count); args.stat = ntohl (piiu->curMsg.m_available); @@ -658,10 +682,11 @@ const struct in_addr *pnet_addr case CA_PROTO_ACCESS_RIGHTS: { int ar; - chid chan; + ciu chan; LOCK; - chan = bucketLookupItemUnsignedId(pSlowBucket, &piiu->curMsg.m_cid); + chan = (ciu) bucketLookupItemUnsignedId( + pSlowBucket, &piiu->curMsg.m_cid); UNLOCK; if(!chan){ /* @@ -686,10 +711,10 @@ const struct in_addr *pnet_addr } case CA_PROTO_CLAIM_CIU: { - chid chan; + ciu chan; LOCK; - chan = bucketLookupItemUnsignedId( + chan = (ciu) bucketLookupItemUnsignedId( pSlowBucket, &piiu->curMsg.m_cid); UNLOCK; if(!chan){ @@ -725,10 +750,10 @@ const struct in_addr *pnet_addr */ LOCAL void verifyChanAndDisconnect(IIU *piiu, enum channel_state state) { - chid chan; + ciu chan; LOCK; - chan = bucketLookupItemUnsignedId( + chan = (ciu) bucketLookupItemUnsignedId( pSlowBucket, &piiu->curMsg.m_cid); if (!chan) { /* @@ -761,7 +786,7 @@ const struct in_addr *pnet_addr int v42; unsigned short port; char rej[64]; - chid chan; + ciu chan; int status; IIU *allocpiiu; IIU *chpiiu; @@ -774,7 +799,7 @@ const struct in_addr *pnet_addr * lock required around use of the sprintf buffer */ LOCK; - chan = bucketLookupItemUnsignedId( + chan = (ciu) bucketLookupItemUnsignedId( pSlowBucket, &piiu->curMsg.m_available); if(!chan){ @@ -923,8 +948,8 @@ const struct in_addr *pnet_addr * reconnect_channel() */ LOCAL void reconnect_channel( -IIU *piiu, -chid chan +IIU *piiu, +ciu chan ) { evid pevent; @@ -1007,7 +1032,7 @@ chid chan } else if(prev_cs==cs_never_conn){ /* decrement the outstanding IO count */ - CLRPENDRECV(TRUE); + CLRPENDRECV; } } diff --git a/src/ca/syncgrp.c b/src/ca/syncgrp.c index 8d5c74dab..eadec0d93 100644 --- a/src/ca/syncgrp.c +++ b/src/ca/syncgrp.c @@ -29,6 +29,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.20 1996/07/10 23:30:12 jhill + * fixed GNU warnings + * * Revision 1.19 1996/06/19 17:59:29 jhill * many 3.13 beta changes * @@ -176,7 +179,7 @@ int epicsShareAPI ca_sg_create(CA_SYNC_GID *pgid) UNLOCK; - *(WRITEABLE_CA_SYNC_GID *)pgid = pcasg->id; + *pgid = pcasg->id; return ECA_NORMAL; } @@ -405,7 +408,7 @@ CA_SYNC_GID gid, chtype type, unsigned long count, chid chix, -void *pvalue) +const void *pvalue) { int status; CASGOP *pcasgop; diff --git a/src/ca/vxWorks_depen.c b/src/ca/vxWorks_depen.c index 03f02aac9..1e684d644 100644 --- a/src/ca/vxWorks_depen.c +++ b/src/ca/vxWorks_depen.c @@ -29,6 +29,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.26 1996/09/16 16:39:20 jhill + * local except => except handler + * * Revision 1.25 1996/08/13 23:16:23 jhill * removed os specific code * @@ -421,8 +424,8 @@ void cac_os_depen_exit (struct ca_static *pcas) LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) { int status; - chid chix; - evid monix; + ciu chix; + miu monix; TVIU *ptviu; CALLBACK *pcb; @@ -449,7 +452,7 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) status = taskSuspend (pcas->recv_tid); if (status<0) { ca_printf ("taskSuspend() error = %s\n", - strerror (MYERRNO) ); + strerror (errno) ); } } } @@ -459,9 +462,9 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) * (and put call backs) * */ - chix = (chid) & pcas->ca_local_chidlist.node; - while (chix = (chid) chix->node.next) { - while (monix = (evid) ellGet(&chix->eventq)) { + chix = (ciu) & pcas->ca_local_chidlist.node; + while ( (chix = (ciu) chix->node.next) ) { + while ( (monix = (miu) ellGet(&chix->eventq)) ) { /* * temp release lock so that the event task * can finish @@ -498,7 +501,7 @@ LOCAL int cac_os_depen_exit_tid (struct ca_static *pcas, int tid) * * db_close_events() does not require a CA context. */ - while (ptviu = (TVIU *)ellGet(&pcas->ca_taskVarList)) { + while ( (ptviu = (TVIU *)ellGet(&pcas->ca_taskVarList)) ) { # ifdef DEBUG ca_printf("CAC: removing task var %x\n", ptviu->tid); # endif diff --git a/src/ca/windows_depen.c b/src/ca/windows_depen.c index a2bc04e81..28f7f7516 100644 --- a/src/ca/windows_depen.c +++ b/src/ca/windows_depen.c @@ -32,6 +32,9 @@ * Modification Log: * ----------------- * $Log$ + * Revision 1.22 1996/09/16 16:40:13 jhill + * make EPICS version be the console title + * * Revision 1.21 1996/08/05 19:20:29 jhill * removed incorrect ver number * @@ -40,6 +43,9 @@ * * Revision 1.19 1995/11/29 19:15:42 jhill * added $Log$ + * added Revision 1.22 1996/09/16 16:40:13 jhill + * added make EPICS version be the console title + * added * added Revision 1.21 1996/08/05 19:20:29 jhill * added removed incorrect ver number * added @@ -55,6 +61,7 @@ #include #include #include + #include #include "iocinf.h" @@ -263,7 +270,7 @@ int local_addr (SOCKET s, struct sockaddr_in *plcladdr) plcladdr->sin_family = AF_INET; plcladdr->sin_port = 0; - plcladdr->sin_addr.s_addr = ntohl (loopBackAddress); + plcladdr->sin_addr.s_addr = htonl (loopBackAddress); return OK; } @@ -271,24 +278,27 @@ int local_addr (SOCKET s, struct sockaddr_in *plcladdr) /* * caDiscoverInterfaces() * - * This routine is provided with the address of an ELLLIST a socket - * and a destination port number. When the routine returns there - * will be one additional inet address (a caAddrNode) in the list - * for each inet interface found that is up and isnt a loop back - * interface. If the interface supports broadcast then I add its - * broadcast address to the list. If the interface is a point to - * point link then I add the destination address of the point to - * point link to the list. In either case I set the port number - * in the address node to the port supplied in the argument - * list. + * This routine is provided with the address of an ELLLIST, a socket + * a destination port number, and a match address. When the + * routine returns there will be one additional inet address + * (a caAddrNode) in the list for each inet interface found that + * is up and isnt a loop back interface (match addr is INADDR_ANY) + * or it matches the specified interface (match addr isnt INADDR_ANY). + * If the interface supports broadcast then I add its broadcast + * address to the list. If the interface is a point to + * point link then I add the destination address of the point to + * point link to the list. In either case I set the port number + * in the address node to the port supplied in the argument + * list. * * LOCK should be applied here for (pList) * (this is also called from the server) */ -void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port) +void caDiscoverInterfaces(ELLLIST *pList, SOCKET socket, int port, + stuct in_addr matchAddr) { struct in_addr bcast_addr; - caAddrNode *pNode; + caAddrNode *pNode; pNode = (caAddrNode *) calloc(1,sizeof(*pNode)); if(!pNode){ @@ -323,7 +333,7 @@ broadcast_addr( struct in_addr *pcastaddr ) gethostname(lhostname,sizeof(lhostname)); phostent = gethostbyname(lhostname); if (!phostent) { - return MYERRNO; + return SOCKERRNO; } if (status = get_subnet_mask(netmask)) diff --git a/src/include/cadef.h b/src/include/cadef.h index d5e646b8c..8a5c4c4a4 100644 --- a/src/include/cadef.h +++ b/src/include/cadef.h @@ -121,8 +121,18 @@ HDRVERSIONID(cadefh, "@(#) $Id$") */ #define ca_field_type(CHID) ((CHID)->type) #define ca_element_count(CHID) ((CHID)->count) -#define ca_name(CHID) ((char *)((CHID)+1)) -#define ca_puser(CHID) ((CHID)->puser) +#define ca_name(CHID) ((READONLY char *)((CHID)+1)) +/* + * the odd cast here removes const (and allows past practice + * of using ca_puser(CHID) as an lvalue. + */ +#define ca_puser(CHID) (*(void **)&((CHID)->puser)) +/* + * here is the preferred way to load the puser ptr associated with + * channel (the cast removes const) + */ +#define ca_set_puser(CHID,PUSER) \ +(((struct channel_in_use *)CHID)->puser=(PUSER)) #define ca_host_name(CHID) ca_host_name_function(CHID) #define ca_read_access(CHID) ((CHID)->ar.read_access) #define ca_write_access(CHID) ((CHID)->ar.write_access) @@ -147,7 +157,8 @@ typedef struct ca_access_rights{ /* Format for the arguments to user connection handlers */ struct channel_in_use; struct connection_handler_args{ - struct channel_in_use *chid; /* Channel id */ + READONLY struct channel_in_use + *chid; /* Channel id */ long op; /* External codes for CA op */ }; @@ -159,7 +170,8 @@ typedef void caCh(); /* Format for the arguments to user access rights handlers */ struct access_rights_handler_args{ - struct channel_in_use *chid; /* Channel id */ + READONLY struct channel_in_use + *chid; /* Channel id */ caar ar; /* New access rights state */ }; @@ -176,9 +188,9 @@ struct channel_in_use{ unsigned short count; /* array element count */ union{ unsigned sid; /* server id */ - struct db_addr *paddr; /* database address */ + struct dbAddr *paddr; /* database address */ } id; - void *puser; /* user available area */ + READONLY void *puser; /* user available area */ enum channel_state state; /* connected/ disconnected etc */ caar ar; /* access rights */ @@ -200,10 +212,10 @@ struct channel_in_use{ */ }; -typedef struct channel_in_use *chid; -typedef long chtype; -typedef struct pending_event *evid; -typedef double ca_real; +typedef READONLY struct channel_in_use *chid; +typedef long chtype; +typedef READONLY struct pending_event *evid; +typedef double ca_real; /* The conversion routine to call for each type */ #define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE) @@ -211,34 +223,35 @@ typedef double ca_real; /* argument passed to event handlers and callback handlers */ struct event_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use *chid; /* Channel id */ - long type; /* the type of the value returned */ - long count; /* the element count of the item returned */ - void *dbr; /* Pointer to the value returned */ - int status; /* CA Status of the op from server - CA V4.1 */ + void *usr; /* User argument supplied when event added */ + READONLY struct channel_in_use + *chid; /* Channel id */ + long type; /* the type of the value returned */ + long count; /* the element count of the item returned */ + READONLY void *dbr; /* Pointer to the value returned */ + int status; /* CA Status of the op from server - CA V4.1 */ }; struct pending_event{ - ELLNODE node; /* list ptrs */ + ELLNODE node; /* list ptrs */ #ifdef CAC_FUNC_PROTO - void (*usr_func)(struct event_handler_args args); + void (*usr_func)(struct event_handler_args args); #else /*CAC_FUNC_PROTO*/ - void (*usr_func)(); + void (*usr_func)(); #endif /*CAC_FUNC_PROTO*/ - void *usr_arg; - struct channel_in_use *chan; - chtype type; /* requested type for local CA */ - unsigned long count; /* requested count for local CA */ + READONLY void *usr_arg; + chid chan; + chtype type; /* requested type for local CA */ + unsigned long count; /* requested count for local CA */ /* * the following provide for reissuing a * disconnected monitor */ - ca_real p_delta; - ca_real n_delta; - ca_real timeout; - unsigned id; - unsigned short mask; + ca_real p_delta; + ca_real n_delta; + ca_real timeout; + unsigned id; + unsigned short mask; }; void epicsShareAPI ca_test_event @@ -250,16 +263,17 @@ void epicsShareAPI ca_test_event /* Format for the arguments to user exception handlers */ struct exception_handler_args{ - void *usr; /* User argument supplied when event added */ - struct channel_in_use *chid; /* Channel id */ - long type; /* Requested type for the operation */ - long count; /* Requested count for the operation */ - void *addr; /* User's address to write results of CA_OP_GET */ - long stat; /* Channel access std status code */ - long op; /* External codes for channel access operations */ - char *ctx; /* A character string containing context info */ - char *pFile; /* source file name (may be NULL) */ - unsigned lineNo; /* source file line number */ + void *usr; /* User argument supplied when event added */ + READONLY struct channel_in_use + *chid; /* Channel id */ + long type; /* Requested type for the operation */ + long count; /* Requested count for the operation */ + void *addr; /* User's address to write results of CA_OP_GET */ + long stat; /* Channel access std status code */ + long op; /* External codes for channel access operations */ + const char *ctx; /* A character string containing context info */ + const char *pFile; /* source file name (may be NULL) */ + unsigned lineNo; /* source file line number */ }; @@ -303,29 +317,9 @@ int epicsShareAPI ca_task_exit #endif /*CAC_FUNC_PROTO*/ ); - -/************************************************************************/ -/* Return a channel identification for the supplied channel name */ -/* (and attempt to create a virtual circuit) */ -/************************************************************************/ - -/* - * preferred search mechanism - */ -#define ca_search(NAME,CHIDPTR)\ -ca_search_and_connect(NAME, CHIDPTR, 0, 0) -/* ca_search - ( - Name IO Value - ---- -- ----- -char *, NAME R NULL term ASCII channel name string -chid * CHIDPTR RW channel index written here - ); -*/ - /************************************************************************ - * anachronistic entry points * - * **** Fetching a value while searching nolonger supported**** * + * anachronistic entry points * + * **** Fetching a value while searching nolonger supported**** * ************************************************************************/ #define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) @@ -334,54 +328,76 @@ ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) +/************************************************************************/ +/* Return a channel identification for the supplied channel name */ +/* (and attempt to create a virtual circuit) */ +/************************************************************************/ + /* - * preferred search mechanism + * preferred search request API + */ +#define ca_search(NAME,CHIDPTR)\ +ca_search_and_connect(NAME, CHIDPTR, 0, 0) +/* ca_search + ( + Name IO Value + ---- -- ----- +const char *, NAME R NULL term ASCII channel name string +chid * CHIDPTR RW channel index written here + ); +*/ + + +/* + * preferred search request API */ int epicsShareAPI ca_search_and_connect ( #ifdef CAC_FUNC_PROTO /* Name IO Value */ /* ---- -- ----- */ -char *,/* NAME R NULL term ASCII channel name string */ -chid *,/* CHIDPTR RW channel index written here */ +const char *, + /* NAME R NULL term ASCII channel name string */ +chid *, /* CHIDPTR RW channel index written here */ void (*)(struct connection_handler_args), /* PFUNC R the address of user's connection handler*/ -void * /* PUSER R placed in the channel's puser field */ +const void * + /* PUSER R placed in the channel's puser field */ #endif /*CAC_FUNC_PROTO*/ ); /************************************************************************ - * anachronistic entry point * - * **** Fetching a value while searching nolonger supported**** * + * anachronistic entry point * + * **** Fetching a value while searching nolonger supported**** * ************************************************************************/ int epicsShareAPI ca_build_and_connect - ( -#ifdef CAC_FUNC_PROTO - /* Name IO Value */ - /* ---- -- ----- */ -char *, /* NAME R NULL term ASCII channel name string */ -chtype, /* GET_TYPE R external channel type to get */ -unsigned/* (no get if invalid type) */ -long, /* GET_COUNT R array count to get */ -chid *, /* CHIDPTR RW channel index written here */ -void *, /* PVALUE W A pointer to a user supplied buffer */ + ( +#ifdef CAC_FUNC_PROTO + /* Name IO Value */ + /* ---- -- ----- */ +char *, /* NAME R NULL term ASCII channel name string */ +chtype, /* GET_TYPE R external channel type to get */ +unsigned/* (no get if invalid type) */ +long, /* GET_COUNT R array count to get */ +chid *, /* CHIDPTR RW channel index written here */ +void *, /* PVALUE W A pointer to a user supplied buffer */ void (*)(struct connection_handler_args), - /* PFUNC R the address of user's connection handler*/ -void * /* PUSER R placed in the channel's puser field */ + /* PFUNC R the address of user's connection handler*/ +void * /* PUSER R placed in the channel's puser field */ #endif /*CAC_FUNC_PROTO*/ - ); + ); int epicsShareAPI ca_change_connection_event ( #ifdef CAC_FUNC_PROTO -chid chix, +chid chan, void (*pfunc)(struct connection_handler_args) #endif /*CAC_FUNC_PROTO*/ ); int epicsShareAPI ca_replace_access_rights_event( #ifdef CAC_FUNC_PROTO -chid chix, +chid chan, void (*pfunc)(struct access_rights_handler_args) #endif /*CAC_FUNC_PROTO*/ ); @@ -395,7 +411,7 @@ int epicsShareAPI ca_add_exception_event ( #ifdef CAC_FUNC_PROTO void (*pfunc)(struct exception_handler_args), -void *arg +const void *arg #endif /*CAC_FUNC_PROTO*/ ); @@ -419,7 +435,7 @@ chid /* CHAN, R channel identifier */ C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -char * PVALUE R pointer to a binary value string +const char * PVALUE R pointer to a binary value string */ #define ca_rput(CHID,PVALUE)\ @@ -428,7 +444,8 @@ ca_array_put(DBR_FLOAT, 1, CHID, (PVALUE)) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -dbr_float_t * PVALUE R pointer to a real value +const dbr_float_t * + PVALUE R pointer to a real value */ #define ca_put(CHTYPE, CHID, PVALUE) ca_array_put(CHTYPE, 1, CHID, PVALUE) @@ -437,7 +454,7 @@ dbr_float_t * PVALUE R pointer to a real value ---- -- ----- chtype, TYPE R channel type chid, CHID R channel index -void * PVALUE R pointer to new channel value of type specified +const void * PVALUE R pointer to new channel value of type specified i.e. status = ca_put(DBF_INT,chid,&value) */ @@ -450,7 +467,8 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void * /* PVALUE R pointer to new channel value of type */ +const void * + /* PVALUE R pointer to new channel value of type */ /* specified. */ #endif /*CAC_FUNC_PROTO*/ ); @@ -472,10 +490,12 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void *, /* PVALUE R pointer to new channel value of type */ +const void *, + /* PVALUE R pointer to new channel value of type */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void * /* USRARG R An argument copied to the above function*/ +const void * + /* USRARG R An argument copied to the above function*/ #endif /*CAC_FUNC_PROTO*/ ); @@ -492,7 +512,7 @@ void * /* USRARG R An argument copied to the above function*/ C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -char * PVALUE W string value pointer +char * PVALUE W string value pointer */ #define ca_rget(CHID,PVALUE) ca_array_get(DBR_FLOAT, 1, CHID, PVALUE) @@ -536,8 +556,9 @@ ca_array_get_callback(DBR_STRING, 1, CHID, PFUNC, ARG) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ #define ca_rget_callback(CHID,PFUNC,ARG)\ @@ -547,8 +568,9 @@ ca_array_get_callback(DBR_FLOAT, 1, CHID, PFUNC, ARG) C Type Name IO Value ------ ----- -- ----- chid CHID R channel id -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ #define ca_get_callback(CHTYPE, CHID,PFUNC,ARG)\ @@ -558,8 +580,9 @@ C Type Name IO Value ------ ----- -- ----- chtype, TYPE R channel type chid, CHID R channel index -void (*)(), PFUNC R the address of a user supplied function -void *, ARG R An argument copied to the above function +void (*)(struct event_handler_args), + PFUNC R the address of a user supplied function +const void *, ARG R An argument copied to the above function */ int epicsShareAPI ca_array_get_callback @@ -573,7 +596,8 @@ unsigned long, chid, /* CHID R channel index */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void * /* USRARG R An argument copied to the above function */ +const void * + /* USRARG R An argument copied to the above function */ #endif /*CAC_FUNC_PROTO*/ ); @@ -597,9 +621,9 @@ ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,0.0,0.0,0.0,EVID) /* Name IO Value ---- -- ----- chid, CHID R channel index -void -(*)(), USRFUNC R the address of a user supplied function -void *, USRARG R An argument copied to the above function +void (*)(struct event_handler_args), + USRFUNC R the address of a user supplied function +const void *, USRARG R An argument copied to the above function evid * EVIDPTR W An id to refer to this event by */ @@ -611,9 +635,9 @@ evid * EVIDPTR W An id to refer to this event by /* Name IO Value ---- -- ----- chid, CHID R channel index -void -(*)(), USRFUNC R the address of a user supplied function -void *, USRARG R An argument copied to the above function +void (*)(struct event_handler_args), + USRFUNC R the address of a user supplied function +const void *, USRARG R An argument copied to the above function ca_real, DELTA R Generate events after +-delta excursions evid * EVIDPTR W An id to refer to this event by */ @@ -638,7 +662,8 @@ unsigned long, chid, /* CHID R channel index */ void (*)(struct event_handler_args), /* USRFUNC R the address of a user supplied function */ -void *, /* USRARG R An argument copied to the above function*/ +const void *, + /* USRARG R An argument copied to the above function*/ ca_real,/* P_DELTA R Generate events after +delta excursions */ ca_real,/* N_DELTA R Generate events after -delta excursions */ ca_real,/* TIMEOUT R Generate events after timeout sec */ @@ -754,7 +779,8 @@ void epicsShareAPI ca_signal /* Name IO Value */ /* ---- -- ----- */ long, /* CODE R status returned from channel access function */ -char * /* MSG R null term string printed on error */ +const char * + /* MSG R null term string printed on error */ #endif /*CAC_FUNC_PROTO*/ ); @@ -764,8 +790,10 @@ void epicsShareAPI ca_signal_with_file_and_lineno /* Name IO Value */ /* ---- -- ----- */ long, /* CODE R status returned from channel access function */ -char *, /* MSG R null term string printed on error */ -char *, /* FILE R pointer to null terminated file name string */ +const char *, + /* MSG R null term string printed on error */ +const char *, + /* FILE R pointer to null terminated file name string */ int /* LINENO R line number */ #endif /*CAC_FUNC_PROTO*/ ); @@ -785,7 +813,7 @@ int /* LINENO R line number */ __LINE__); \ } -char * epicsShareAPI ca_host_name_function +const char * epicsShareAPI ca_host_name_function ( #ifdef CAC_FUNC_PROTO /* Name IO Value */ @@ -814,7 +842,7 @@ typedef void CAFDHANDLER(); int epicsShareAPI ca_add_fd_registration( #ifdef CAC_FUNC_PROTO CAFDHANDLER *pHandler, -void *pArg +const void *pArg #endif /*CAC_FUNC_PROTO*/ ); @@ -851,12 +879,7 @@ int ca_import_cancel(); * IO operations are initiated then the programmer is free to * block for IO completion within any one of the groups as needed. */ -typedef unsigned WRITEABLE_CA_SYNC_GID; -#ifdef CAC_FUNC_PROTO -typedef const unsigned CA_SYNC_GID; -#else typedef unsigned CA_SYNC_GID; -#endif /* * create a sync group @@ -936,7 +959,8 @@ chtype, /* TYPE R channel type */ unsigned long, /* COUNT R array element count */ chid, /* CHID R channel index */ -void * /* PVALUE R pointer to new channel value of type */ +const void * + /* PVALUE R pointer to new channel value of type */ /* specified. */ #endif /*CAC_FUNC_PROTO*/ ); @@ -957,7 +981,7 @@ int epicsShareAPI ca_sg_stat(); * client user name. */ #ifdef CAC_FUNC_PROTO -int epicsShareAPI ca_modify_user_name(char *pUserName); +int epicsShareAPI ca_modify_user_name(const char *pUserName); #else /*CAC_FUNC_PROTO*/ int epicsShareAPI ca_modify_user_name(); #endif /*CAC_FUNC_PROTO*/ @@ -969,7 +993,7 @@ int epicsShareAPI ca_modify_user_name(); * client host name. */ #ifdef CAC_FUNC_PROTO -int epicsShareAPI ca_modify_host_name(char *pHostName); +int epicsShareAPI ca_modify_host_name(const char *pHostName); #else /*CAC_FUNC_PROTO*/ int epicsShareAPI ca_modify_host_name(); #endif /*CAC_FUNC_PROTO*/ diff --git a/src/include/caerr.h b/src/include/caerr.h index 453384534..50469b3f5 100644 --- a/src/include/caerr.h +++ b/src/include/caerr.h @@ -154,7 +154,7 @@ HDRVERSIONID(caerrh, "@(#) $Id$") #ifndef CA_ERROR_GLBLSOURCE -epicsShareExtern READONLY char *ca_message_text[]; +epicsShareExtern READONLY char *epicsShareAPI ca_message_text[]; #else READONLY char *ca_message_text[] =