diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index a527844fb..23523aaab 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -13,6 +13,13 @@ +
Array handling in the caget and camonitor programs has been debugged, fixing +launchpad bug 794749 along +with a few other related issues dating back to the addition of variable length +array support.
+If it was still busy when the IOC was closed down, the errlog thread could diff --git a/src/catools/caget.c b/src/catools/caget.c index ac742fc73..a2b0e08b0 100644 --- a/src/catools/caget.c +++ b/src/catools/caget.c @@ -126,7 +126,6 @@ static void event_handler (evargs args) ppv->dbrType = args.type; ppv->value = calloc(1, dbr_size_n(args.type, args.count)); memcpy(ppv->value, args.dbr, dbr_size_n(args.type, args.count)); - ppv->onceConnected = 1; ppv->nElems = args.count; nRead++; } @@ -159,12 +158,13 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format, int n, result; for (n = 0; n < nPvs; n++) { + unsigned long nElems; /* Set up pvs structure */ /* -------------------- */ /* Get natural type and array count */ - pvs[n].nElems = ca_element_count(pvs[n].chid); + nElems = ca_element_count(pvs[n].chid); pvs[n].dbfType = ca_field_type(pvs[n].chid); pvs[n].dbrType = dbrType; @@ -183,10 +183,6 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format, pvs[n].dbrType = DBR_TIME_STRING; } } - /* Adjust array count */ - if (reqElems > pvs[n].nElems) - reqElems = pvs[n].nElems; - pvs[n].reqElems = reqElems; /* Issue CA request */ /* ---------------- */ @@ -196,21 +192,24 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format, nConn++; pvs[n].onceConnected = 1; if (request == callback) - { /* Event handler will allocate value */ + { + /* Event handler will allocate value and set nElems */ + pvs[n].reqElems = reqElems > nElems ? nElems : reqElems; result = ca_array_get_callback(pvs[n].dbrType, pvs[n].reqElems, pvs[n].chid, event_handler, (void*)&pvs[n]); } else { - /* Allocate value structure */ + /* We allocate value structure and set nElems */ + pvs[n].nElems = reqElems && reqElems < nElems ? reqElems : nElems; pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems)); - if(!pvs[n].value) { - fprintf(stderr,"Allocation failed\n"); + if (!pvs[n].value) { + fprintf(stderr,"Memory allocation failed\n"); return 1; } result = ca_array_get(pvs[n].dbrType, - pvs[n].reqElems, + pvs[n].nElems, pvs[n].chid, pvs[n].value); } @@ -252,9 +251,6 @@ static int caget (pv *pvs, int nPvs, RequestT request, OutputT format, /* -------------- */ for (n = 0; n < nPvs; n++) { - /* Truncate the data printed to what was requested. */ - if (pvs[n].reqElems != 0 && pvs[n].nElems > pvs[n].reqElems) - pvs[n].nElems = pvs[n].reqElems; switch (format) { case plain: /* Emulate old caget behaviour */ @@ -377,7 +373,7 @@ static void complainIfNotPlainAndSet (OutputT *current, const OutputT requested) int main (int argc, char *argv[]) { - int n = 0; + int n; int result; /* CA result */ OutputT format = plain; /* User specified format */ RequestT request = get; /* User specified request type */ @@ -389,7 +385,7 @@ int main (int argc, char *argv[]) int digits = 0; /* getopt() no. of float digits */ int nPvs; /* Number of PVs */ - pv* pvs = 0; /* Array of PV structures */ + pv* pvs; /* Array of PV structures */ LINE_BUFFER(stdout); /* Configure stdout buffering */ @@ -529,7 +525,7 @@ int main (int argc, char *argv[]) result = ca_context_create(ca_disable_preemptive_callback); if (result != ECA_NORMAL) { fprintf(stderr, "CA error %s occurred while trying " - "to start channel access '%s'.\n", ca_message(result), pvs[n].name); + "to start channel access.\n", ca_message(result)); return 1; } /* Allocate PV structure array */ diff --git a/src/catools/cainfo.c b/src/catools/cainfo.c index a287f6984..924c34b10 100644 --- a/src/catools/cainfo.c +++ b/src/catools/cainfo.c @@ -127,13 +127,13 @@ int cainfo (pv *pvs, int nPvs) int main (int argc, char *argv[]) { - int n = 0; + int n; int result; /* CA result */ int opt; /* getopt() current option */ int nPvs; /* Number of PVs */ - pv* pvs = 0; /* Array of PV structures */ + pv* pvs; /* Array of PV structures */ LINE_BUFFER(stdout); /* Configure stdout buffering */ @@ -195,7 +195,7 @@ int main (int argc, char *argv[]) result = ca_context_create(ca_disable_preemptive_callback); if (result != ECA_NORMAL) { fprintf(stderr, "CA error %s occurred while trying " - "to start channel access '%s'.\n", ca_message(result), pvs[n].name); + "to start channel access.\n", ca_message(result)); return 1; } /* Allocate PV structure array */ diff --git a/src/catools/camonitor.c b/src/catools/camonitor.c index 617ee7622..cda00989f 100644 --- a/src/catools/camonitor.c +++ b/src/catools/camonitor.c @@ -92,7 +92,7 @@ void usage (void) * Function: event_handler * * Description: CA event_handler for request type callback - * Allocates the dbr structure and copies the data + * Prints the event data * * Arg(s) In: args - event handler args (see CA manual) * @@ -107,10 +107,12 @@ static void event_handler (evargs args) { pv->dbrType = args.type; pv->nElems = args.count; - memcpy(pv->value, args.dbr, dbr_size_n(args.type, args.count)); + pv->value = (void *) args.dbr; /* casting away const */ print_time_val_sts(pv, reqElems); fflush(stdout); + + pv->value = NULL; } } @@ -129,51 +131,39 @@ static void connection_handler ( struct connection_handler_args args ) { pv *ppv = ( pv * ) ca_puser ( args.chid ); if ( args.op == CA_OP_CONN_UP ) { + nConn++; + if (!ppv->onceConnected) { + ppv->onceConnected = 1; /* Set up pv structure */ /* ------------------- */ /* Get natural type and array count */ - ppv->nElems = ca_element_count(ppv->chid); - ppv->dbfType = ca_field_type(ppv->chid); + ppv->dbfType = ca_field_type(ppv->chid); + ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */ + if (dbr_type_is_ENUM(ppv->dbrType)) /* Enums honour -n option */ + { + if (enumAsNr) ppv->dbrType = DBR_TIME_INT; + else ppv->dbrType = DBR_TIME_STRING; + } + else if (floatAsString && + (dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType))) + { + ppv->dbrType = DBR_TIME_STRING; + } + /* Set request count */ + ppv->nElems = ca_element_count(ppv->chid); + ppv->reqElems = reqElems > ppv->nElems ? ppv->nElems : reqElems; - /* Set up value structures */ - ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */ - if (dbr_type_is_ENUM(ppv->dbrType)) /* Enums honour -n option */ - { - if (enumAsNr) ppv->dbrType = DBR_TIME_INT; - else ppv->dbrType = DBR_TIME_STRING; - } - - else if (floatAsString && - (dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType))) - { - ppv->dbrType = DBR_TIME_STRING; - } - /* Adjust array count */ - if (reqElems > ppv->nElems) - reqElems = ppv->nElems; - ppv->reqElems = reqElems; - - ppv->onceConnected = 1; - nConn++; /* Issue CA request */ /* ---------------- */ - /* install monitor once with first connect */ - if ( ! ppv->value ) { - /* Allocate value structure */ - ppv->value = calloc(1, dbr_size_n(ppv->dbrType, ppv->nElems)); - if ( ppv->value ) { - ppv->status = ca_create_subscription(ppv->dbrType, + /* install monitor once with first connect */ + ppv->status = ca_create_subscription(ppv->dbrType, ppv->reqElems, ppv->chid, eventMask, event_handler, (void*)ppv, NULL); - if ( ppv->status != ECA_NORMAL ) { - free ( ppv->value ); - } - } } } else if ( args.op == CA_OP_CONN_DOWN ) { @@ -203,7 +193,7 @@ static void connection_handler ( struct connection_handler_args args ) int main (int argc, char *argv[]) { int returncode = 0; - int n = 0; + int n; int result; /* CA result */ IntFormatT outType; /* Output type */ @@ -211,7 +201,7 @@ int main (int argc, char *argv[]) int digits = 0; /* getopt() no. of float digits */ int nPvs; /* Number of PVs */ - pv* pvs = 0; /* Array of PV structures */ + pv* pvs; /* Array of PV structures */ LINE_BUFFER(stdout); /* Configure stdout buffering */ @@ -356,7 +346,7 @@ int main (int argc, char *argv[]) result = ca_context_create(ca_disable_preemptive_callback); if (result != ECA_NORMAL) { fprintf(stderr, "CA error %s occurred while trying " - "to start channel access '%s'.\n", ca_message(result), pvs[n].name); + "to start channel access.\n", ca_message(result)); return 1; } /* Allocate PV structure array */ diff --git a/src/catools/caput.c b/src/catools/caput.c index 9aaba38dc..62815b104 100644 --- a/src/catools/caput.c +++ b/src/catools/caput.c @@ -251,7 +251,7 @@ int caget (pv *pvs, int nPvs, OutputT format, int main (int argc, char *argv[]) { - int n = 0; + int n; int i; int result; /* CA result */ OutputT format = plain; /* User specified format */ @@ -273,7 +273,7 @@ int main (int argc, char *argv[]) struct dbr_gr_enum bufGrEnum; int nPvs; /* Number of PVs */ - pv* pvs = 0; /* Array of PV structures */ + pv* pvs; /* Array of PV structures */ LINE_BUFFER(stdout); /* Configure stdout buffering */ putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */ @@ -372,7 +372,7 @@ int main (int argc, char *argv[]) result = ca_context_create(ca_enable_preemptive_callback); if (result != ECA_NORMAL) { fprintf(stderr, "CA error %s occurred while trying " - "to start channel access '%s'.\n", ca_message(result), pvs[n].name); + "to start channel access.\n", ca_message(result)); return 1; } /* Allocate PV structure array */