int NewClient(void) { int i, sz; for (i = 0; i < nClients; i++) if (!client[i].status.connected) break; if (i == clientSize) { clientSize = clientSize ? clientSize * 2 : MIN_CLIENTS_ALLOC; sz = sizeof(ClientInfo) * clientSize; client = (ClientInfo *) realloc(client, sz); if (client == NULL) { __pmNoMem("NewClient", sz, PM_RECOV_ERR); Shutdown(); exit(1); } sz -= (sizeof(ClientInfo) * i); memset(&client[i], 0, sz); } client[i].addr = __pmSockAddrAlloc(); if (client[i].addr == NULL) { __pmNoMem("NewClient", __pmSockAddrSize(), PM_RECOV_ERR); Shutdown(); exit(1); } if (i >= nClients) nClients = i + 1; return i; }
static pmResult * MakeBadResult(int npmids, pmID *list, int sts) { int need; int i; pmValueSet *vSet; pmResult *result; need = (int)sizeof(pmResult) + (npmids - 1) * (int)sizeof(pmValueSet *); /* npmids - 1 because there is already 1 pmValueSet* in a pmResult */ result = (pmResult *)malloc(need); if (result == NULL) { __pmNoMem("MakeBadResult.result", need, PM_FATAL_ERR); } result->numpmid = npmids; for (i = 0; i < npmids; i++) { vSet = (pmValueSet *)malloc(sizeof(pmValueSet)); if (vSet == NULL) { __pmNoMem("MakeBadResult.vSet", sizeof(pmValueSet), PM_FATAL_ERR); } result->vset[i] = vSet; vSet->pmid = list[i]; vSet->numval = sts; } return result; }
static void newHashInst(pmValue *vp, checkData *checkdata, /* updated by this function */ int valfmt, struct timeval *timestamp, /* timestamp for this sample */ int pos) /* position of this inst in instlist */ { int sts; size_t size; pmAtomValue av; if ((sts = pmExtractValue(valfmt, vp, checkdata->desc.type, &av, PM_TYPE_DOUBLE)) < 0) { fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol); print_stamp(stderr, timestamp); fprintf(stderr, "] "); print_metric(stderr, checkdata->desc.pmid); fprintf(stderr, ": pmExtractValue failed: %s\n", pmErrStr(sts)); fprintf(stderr, "%s: possibly corrupt archive?\n", pmProgname); exit(EXIT_FAILURE); } size = (pos+1)*sizeof(instData*); checkdata->instlist = (instData**) realloc(checkdata->instlist, size); if (!checkdata->instlist) __pmNoMem("newHashInst.instlist", size, PM_FATAL_ERR); size = sizeof(instData); checkdata->instlist[pos] = (instData*) malloc(size); if (!checkdata->instlist[pos]) __pmNoMem("newHashInst.instlist[pos]", size, PM_FATAL_ERR); checkdata->instlist[pos]->inst = vp->inst; checkdata->instlist[pos]->lastval = av.d; checkdata->instlist[pos]->lasttime = *timestamp; checkdata->listsize++; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) { char *name; fprintf(stderr, "%s.%d:[", l_archname, l_ctxp->c_archctl->ac_vol); print_stamp(stderr, timestamp); fprintf(stderr, "] "); print_metric(stderr, checkdata->desc.pmid); if (vp->inst == PM_INDOM_NULL) fprintf(stderr, ": new singular metric\n"); else { fprintf(stderr, ": new metric-instance pair "); if (pmNameInDom(checkdata->desc.indom, vp->inst, &name) < 0) fprintf(stderr, "%d\n", vp->inst); else { fprintf(stderr, "\"%s\"\n", name); free(name); } } } #endif }
int __pmServerAddInterface(const char *address) { size_t size = (nintf+1) * sizeof(char *); char *intf; /* one (of possibly several) IP addresses for client requests */ intflist = (char **)realloc(intflist, nintf * sizeof(char *)); if (intflist == NULL) __pmNoMem("AddInterface: cannot grow interface list", size, PM_FATAL_ERR); if ((intf = strdup(address)) == NULL) __pmNoMem("AddInterface: cannot strdup interface", strlen(address), PM_FATAL_ERR); intflist[nintf++] = intf; return nintf; }
int __pmAddPorts(const char *portstr, int **ports, int nports) { /* * The list of ports referenced by *ports may be (re)allocated * using calls to realloc(3) with a new size based on nports. * For an empty list, *ports must be NULL and nports must be 0. * It is the responsibility of the caller to free this memory. * * If sufficient memory cannot be allocated, then this function * calls __pmNoMem() and does not return. */ char *endptr, *p = (char *)portstr; size_t size; /* * one (of possibly several) ports for client requests * ... accept a comma separated list of ports here */ for ( ; ; ) { int port = (int)strtol(p, &endptr, 0); if ((*endptr != '\0' && *endptr != ',') || port < 0) return -EINVAL; size = (nports + 1) * sizeof(int); if ((*ports = (int *)realloc(*ports, size)) == NULL) __pmNoMem("__pmAddPorts: cannot grow port list", size, PM_FATAL_ERR); (*ports)[nports++] = port; if (*endptr == '\0') break; p = &endptr[1]; } return nports; }
/* * Hostname extracted and cached for later use during protocol negotiations */ static void GetProxyHostname(void) { __pmHostEnt *hep; char host[MAXHOSTNAMELEN]; if (gethostname(host, MAXHOSTNAMELEN) < 0) { __pmNotifyErr(LOG_ERR, "%s: gethostname failure\n", pmProgname); DontStart(); } host[MAXHOSTNAMELEN-1] = '\0'; hep = __pmGetAddrInfo(host); if (hep == NULL) { __pmNotifyErr(LOG_ERR, "%s: __pmGetAddrInfo failure\n", pmProgname); DontStart(); } else { hostname = __pmHostEntGetName(hep); if (!hostname) { /* no reverse DNS lookup for local hostname */ hostname = strdup(host); if (!hostname) /* out of memory, we're having a bad day!?! */ __pmNoMem("PMPROXY.hostname", strlen(host), PM_FATAL_ERR); } __pmHostEntFree(hep); } }
static char * build_short_options(pmOptions *opts) { pmLongOptions *entry; char *shortopts; size_t size; int opt, index = 0; /* allocate for maximal case - every entry has a short opt and an arg */ size = 1 + sizeof(char) * 2 * count; if ((shortopts = malloc(size)) == NULL) __pmNoMem("shortopts", size, PM_FATAL_ERR); for (entry = opts->long_options; entry && entry->long_opt; entry++) { if ((opt = entry->short_opt) == 0) continue; if (opt == '-' || opt == '|' || opt == '"') continue; shortopts[index++] = (char)opt; if (entry->has_arg) shortopts[index++] = ':'; } shortopts[index] = '\0'; return shortopts; }
static int __pmAuthServerSetAttributes(sasl_conn_t *conn, __pmHashCtl *attrs) { const void *property = NULL; char *username; int sts; sts = sasl_getprop(conn, SASL_USERNAME, &property); username = (char *)property; if (sts == SASL_OK && username) { __pmNotifyErr(LOG_INFO, "Successful authentication for user \"%s\"\n", username); if ((username = strdup(username)) == NULL) { __pmNoMem("__pmAuthServerSetAttributes", strlen(username), PM_RECOV_ERR); return -ENOMEM; } } else { __pmNotifyErr(LOG_ERR, "Authentication complete, but no username\n"); return -ESRCH; } if ((sts = __pmHashAdd(PCP_ATTR_USERNAME, username, attrs)) < 0) return sts; return __pmSetUserGroupAttributes(username, attrs); }
int pmiGetHandle(const char *name, const char *instance) { int sts; pmi_handle tmp; pmi_handle *hp; if (current == NULL) return PM_ERR_NOCONTEXT; sts = make_handle(name, instance, &tmp); if (sts != 0) return current->last_sts = sts; current->nhandle++; current->handle = (pmi_handle *)realloc(current->handle, current->nhandle*sizeof(pmi_handle)); if (current->handle == NULL) { __pmNoMem("pmiGetHandle: pmi_handle", current->nhandle*sizeof(pmi_handle), PM_FATAL_ERR); } hp = ¤t->handle[current->nhandle-1]; hp->midx = tmp.midx; hp->inst = tmp.inst; return current->last_sts = current->nhandle; }
static void myvaluesetdump(pmValueSet *xvsp, int idx, int *flagsp) { int sts, flags = *flagsp; DescHash *hp; __pmHashNode *hnp; static __pmHashCtl hash = { 0, 0, NULL }; if ((hnp = __pmHashSearch((unsigned int)xvsp->pmid, &hash)) == NULL) { /* first time for this pmid */ hp = (DescHash *)malloc(sizeof(DescHash)); if (hp == NULL) { __pmNoMem("DescHash", sizeof(DescHash), PM_FATAL_ERR); /*NOTREACHED*/ } if ((sts = pmNameID(xvsp->pmid, &hp->name)) < 0) { printf(" %s: pmNameID: %s\n", pmIDStr(xvsp->pmid), pmErrStr(sts)); free(hp); return; } else { if (xvsp->pmid != pmid_flags && xvsp->pmid != pmid_missed && (sts = pmLookupDesc(xvsp->pmid, &hp->desc)) < 0) { printf(" %s: pmLookupDesc: %s\n", hp->name, pmErrStr(sts)); free(hp->name); free(hp); return; } if ((sts = __pmHashAdd((unsigned int)xvsp->pmid, (void *)hp, &hash)) < 0) { printf(" %s: __pmHashAdd: %s\n", hp->name, pmErrStr(sts)); free(hp->name); free(hp); return; } } } else hp = (DescHash *)hnp->data; if (idx == 0) { if (xvsp->pmid == pmid_flags) { flags = *flagsp = xvsp->vlist[0].value.lval; printf(" flags 0x%x", flags); printf(" (%s) ---\n", pmEventFlagsStr(flags)); return; } else printf(" ---\n"); } if ((flags & PM_EVENT_FLAG_MISSED) && (idx == 1) && (xvsp->pmid == pmid_missed)) { printf(" ==> %d missed event records\n", xvsp->vlist[0].value.lval); return; } mydump(hp->name, &hp->desc, xvsp); }
char * sdup(const char *p) { char *q; if ((q = strdup(p)) == NULL) { __pmNoMem("pmie.sdup", strlen(p), PM_FATAL_ERR); } return q; }
void * ralloc(void *p, size_t size) { void *q; if ((q = realloc(p, size)) == NULL) { __pmNoMem("pmie.ralloc", size, PM_FATAL_ERR); } return q; }
void * zalloc(size_t size) { void *p; if ((p = calloc(1, size)) == NULL) { __pmNoMem("pmie.zalloc", size, PM_FATAL_ERR); } return p; }
int pmiSetTimezone(const char *value) { if (current == NULL) return PM_ERR_NOCONTEXT; current->timezone = strdup(value); if (current->timezone == NULL) { __pmNoMem("pmiSetTimezone", strlen(value)+1, PM_FATAL_ERR); } return current->last_sts = 0; }
static int append_text(pmOptions *opts, char *buffer, size_t length) { pmLongOptions text = PMAPI_OPTIONS_TEXT(""); if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: append: '%s'\n", pmProgname, buffer); if ((text.message = strdup(buffer)) == NULL) __pmNoMem("append_text", length, PM_FATAL_ERR); return append_option(opts, &text); }
static void expand_papi_info(int size) { if (number_of_events <= size) { size_t new_size = (size + 1) * sizeof(papi_m_user_tuple); papi_info = realloc(papi_info, new_size); if (papi_info == NULL) __pmNoMem("papi_info tuple", new_size, PM_FATAL_ERR); while (number_of_events <= size) memset(&papi_info[number_of_events++], 0, sizeof(papi_m_user_tuple)); } }
void enlarge_ctxtab(int context) { /* Grow the context table if necessary. */ if (ctxtab_size /* cardinal */ <= context /* ordinal */) { size_t need = (context + 1) * sizeof(struct uid_gid_tuple); ctxtab = realloc (ctxtab, need); if (ctxtab == NULL) __pmNoMem("systemd ctx table", need, PM_FATAL_ERR); /* Blank out new entries. */ while (ctxtab_size <= context) memset (& ctxtab[ctxtab_size++], 0, sizeof(struct uid_gid_tuple)); } }
/* Increase the capacity of the reqPorts array (maintain the contents) */ static void GrowRequestPorts(void) { size_t need; szReqPorts += 4; need = szReqPorts * sizeof(ReqPortInfo); reqPorts = (ReqPortInfo*)realloc(reqPorts, need); if (reqPorts == NULL) { __pmNoMem("GrowRequestPorts: can't grow request port array", need, PM_FATAL_ERR); } }
/* * This routine opens the config file and stores the information in the * mounts structure. The mounts structure must be reallocated as * necessary, and also the num_procs structure needs to be reallocated * as we define new mounts. When all of that is done, we fill in the * values in the indomtab structure, those being the number of instances * and the pointer to the mounts structure. */ static void mounts_grab_config_info(void) { FILE *fp; char mount_name[MAXPATHLEN]; char *q; size_t size; int mount_number = 0; int sep = __pmPathSeparator(); snprintf(mypath, sizeof(mypath), "%s%c" "mounts" "%c" "mounts.conf", pmGetConfig("PCP_PMDAS_DIR"), sep, sep); if ((fp = fopen(mypath, "r")) == NULL) { __pmNotifyErr(LOG_ERR, "fopen on %s failed: %s\n", mypath, pmErrStr(-oserror())); if (mounts) { free(mounts); mounts = NULL; mount_number = 0; } goto done; } while (fgets(mount_name, sizeof(mount_name), fp) != NULL) { if (mount_name[0] == '#') continue; /* Remove the newline */ if ((q = strchr(mount_name, '\n')) != NULL) { *q = '\0'; } else { /* This means the line was too long */ __pmNotifyErr(LOG_WARNING, "line %d in the config file too long\n", mount_number+1); } size = (mount_number + 1) * sizeof(pmdaInstid); if ((mounts = realloc(mounts, size)) == NULL) __pmNoMem("process", size, PM_FATAL_ERR); mounts[mount_number].i_name = malloc(strlen(mount_name) + 1); strcpy(mounts[mount_number].i_name, mount_name); mounts[mount_number].i_inst = mount_number; mount_number++; } fclose(fp); done: if (mounts == NULL) __pmNotifyErr(LOG_WARNING, "\"mounts\" instance domain is empty"); indomtab[MOUNTS_INDOM].it_set = mounts; indomtab[MOUNTS_INDOM].it_numinst = mount_number; mount_list = realloc(mount_list, (mount_number)*sizeof(mountinfo)); }
static void get_pmids(node_t *np, int *cnt, pmID **list) { assert(np != NULL); if (np->left != NULL) get_pmids(np->left, cnt, list); if (np->right != NULL) get_pmids(np->right, cnt, list); if (np->type == L_NAME) { (*cnt)++; if ((*list = (pmID *)realloc(*list, (*cnt)*sizeof(pmID))) == NULL) { __pmNoMem("__dmprefetch: realloc xtralist", (*cnt)*sizeof(pmID), PM_FATAL_ERR); /*NOTREACHED*/ } (*list)[*cnt-1] = np->info->pmid; } }
/* * Parse non-option commands: getopts, (short)usage, or end. * The return code indicates whether the end directive was observed. */ static int command(pmOptions *opts, char *buffer) { char *start, *finish; start = skip_whitespace(buffer); if (strncasecmp(start, "getopt", sizeof("getopt")-1) == 0) { start = skip_whitespace(skip_nonwhitespace(start)); finish = skip_nonwhitespace(start); *finish = '\0'; if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: getopt command: '%s'\n", pmProgname, start); if ((opts->short_options = strdup(start)) == NULL) __pmNoMem("short_options", strlen(start), PM_FATAL_ERR); return 0; } if (strncasecmp(start, "usage", sizeof("usage")-1) == 0) { start = skip_whitespace(skip_nonwhitespace(start)); if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: usage command: '%s'\n", pmProgname, start); if ((opts->short_usage = strdup(start)) == NULL) __pmNoMem("short_usage", strlen(start), PM_FATAL_ERR); return 0; } if (strncasecmp(start, "end", sizeof("end")-1) == 0) { if (pmDebug & DBG_TRACE_DESPERATE) fprintf(stderr, "%s: end command\n", pmProgname); return 1; } fprintf(stderr, "%s: unrecognized command: '%s'\n", pmProgname, buffer); return 0; }
static void waitawhile(__pmPMCDCtl *ctl) { /* * after failure, compute delay before trying again ... */ PM_LOCK(__pmLock_libpcp); if (n_backoff == 0) { char *q; /* first time ... try for PMCD_RECONNECT_TIMEOUT from env */ if ((q = getenv("PMCD_RECONNECT_TIMEOUT")) != NULL) { char *pend; char *p; int val; for (p = q; *p != '\0'; ) { val = (int)strtol(p, &pend, 10); if (val <= 0 || (*pend != ',' && *pend != '\0')) { __pmNotifyErr(LOG_WARNING, "pmReconnectContext: ignored bad PMCD_RECONNECT_TIMEOUT = '%s'\n", q); n_backoff = 0; if (backoff != NULL) free(backoff); break; } if ((backoff = (int *)realloc(backoff, (n_backoff+1) * sizeof(backoff[0]))) == NULL) { __pmNoMem("pmReconnectContext", (n_backoff+1) * sizeof(backoff[0]), PM_FATAL_ERR); } backoff[n_backoff++] = val; if (*pend == '\0') break; p = &pend[1]; } } if (n_backoff == 0) { /* use default */ n_backoff = 5; backoff = def_backoff; } } PM_UNLOCK(__pmLock_libpcp); if (ctl->pc_timeout == 0) ctl->pc_timeout = 1; else if (ctl->pc_timeout < n_backoff) ctl->pc_timeout++; ctl->pc_again = time(NULL) + backoff[ctl->pc_timeout-1]; }
/* * For block devices we have one instance domain for dev_t * based lookup, and another for (real) name lookup. * The reason we need this is that the blkio cgroup stats * are exported using the major:minor numbers, and not the * device names - we must perform that mapping ourselves. * In some places (value refresh) we need to lookup the blk * name from device major/minor, in other places (instances * refresh) we need the usual external instid:name lookup. */ static void refresh_cgroup_devices(void) { pmInDom diskindom = INDOM(DISK_INDOM); pmInDom devtindom = INDOM(DEVT_INDOM); char buf[MAXPATHLEN]; FILE *fp; pmdaCacheOp(devtindom, PMDA_CACHE_INACTIVE); pmdaCacheOp(diskindom, PMDA_CACHE_INACTIVE); if ((fp = proc_statsfile("/proc/diskstats", buf, sizeof(buf))) == NULL) return; while (fgets(buf, sizeof(buf), fp) != NULL) { unsigned int major, minor, unused; device_t *dev = NULL; char namebuf[1024]; int inst; if (sscanf(buf, "%u %u %s %u", &major, &minor, namebuf, &unused) != 4) continue; if (_pm_isloop(namebuf) || _pm_isramdisk(namebuf)) continue; if (pmdaCacheLookupName(diskindom, namebuf, &inst, (void **)&dev) < 0 || dev == NULL) { if (!(dev = (device_t *)malloc(sizeof(device_t)))) { __pmNoMem("device", sizeof(device_t), PM_RECOV_ERR); continue; } dev->major = major; dev->minor = minor; } /* keeping track of all fields (major/minor/inst/name) */ pmdaCacheStore(diskindom, PMDA_CACHE_ADD, namebuf, dev); (void)pmdaCacheLookupName(diskindom, namebuf, &dev->inst, NULL); (void)pmdaCacheLookup(diskindom, dev->inst, &dev->name, NULL); snprintf(buf, sizeof(buf), "%u:%u", major, minor); pmdaCacheStore(devtindom, PMDA_CACHE_ADD, buf, (void *)dev); if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "refresh_devices: \"%s\" \"%d:%d\" inst=%d\n", dev->name, dev->major, dev->minor, dev->inst); } fclose(fp); }
static int append_option(pmOptions *opts, pmLongOptions *longopt) { pmLongOptions *entry; size_t size = sizeof(pmLongOptions); /* space for existing entries, new entry and the sentinal */ size = (count + 1) * sizeof(pmLongOptions) + sizeof(pmLongOptions); if ((entry = realloc(opts->long_options, size)) == NULL) __pmNoMem("append", size, PM_FATAL_ERR); opts->long_options = entry; entry += count++; /* if not first entry: find current sentinal, overwrite with new option */ memcpy(entry, longopt, sizeof(pmLongOptions)); memset(entry + 1, 0, sizeof(pmLongOptions)); /* insert new sentinal */ return 0; }
static void expand_values(int size) // XXX: collapse into expand_papi_info() { if (size_of_active_counters <= size) { size_t new_size = (size + 1) * sizeof(long_long); values = realloc(values, new_size); if (values == NULL) __pmNoMem("values", new_size, PM_FATAL_ERR); while (size_of_active_counters <= size) { memset(&values[size_of_active_counters++], 0, sizeof(long_long)); if (pmDebug & DBG_TRACE_APPL0) { __pmNotifyErr(LOG_DEBUG, "memsetting to zero, %d counters\n", size_of_active_counters); } } } }
static node_t * newnode(int type) { node_t *np; np = (node_t *)malloc(sizeof(node_t)); if (np == NULL) { PM_UNLOCK(registered.mutex); __pmNoMem("pmRegisterDerived: newnode", sizeof(node_t), PM_FATAL_ERR); /*NOTREACHED*/ } np->type = type; np->save_last = 0; np->left = NULL; np->right = NULL; np->value = NULL; np->info = NULL; return np; }
static int AddBadHost(struct __pmSockAddr *hostId) { int i, need; for (i = 0; i < nBadHosts; i++) if (__pmSockAddrCompare(hostId, badHost[i]) == 0) /* already there */ return 0; /* allocate more entries if required */ if (nBadHosts == szBadHosts) { szBadHosts += 8; need = szBadHosts * (int)sizeof(badHost[0]); if ((badHost = (__pmSockAddr **)realloc(badHost, need)) == NULL) { __pmNoMem("pmcd.AddBadHost", need, PM_FATAL_ERR); } } badHost[nBadHosts++] = __pmSockAddrDup(hostId); return 1; }
void * aalloc(size_t align, size_t size) { void *p = NULL; int sts = 0; #ifdef HAVE_POSIX_MEMALIGN sts = posix_memalign(&p, align, size); #else #ifdef HAVE_MEMALIGN p = memalign(align, size); if (p == NULL) sts = -1; #else p = malloc(size); if (p == NULL) sts = -1; #endif #endif if (sts != 0) { __pmNoMem("pmie.aalloc", size, PM_FATAL_ERR); } return p; }
/* * Fetch values from sysctl() * * Expect the result to be xpect bytes to match the PCP data size or * anticipated structure size, unless xpect is ==0 in which case the * size test is skipped. */ static int do_sysctl(mib_t *mp, size_t xpect) { /* * Note zero trip if mp->m_data and mp->datalen are already valid * and current */ for ( ; mp->m_fetched == 0; ) { int sts; sts = sysctl(mp->m_mib, (u_int)mp->m_miblen, mp->m_data, &mp->m_datalen, NULL, 0); #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) { fprintf(stderr, "sysctl(%s%s) -> %d (datalen=%d)\n", mp->m_name, mp->m_data == NULL ? " firstcall" : "", sts, (int)mp->m_datalen); } #endif if (sts == 0 && mp->m_data != NULL) { mp->m_fetched = 1; break; } if ((sts == -1 && errno == ENOMEM) || (sts == 0 && mp->m_data == NULL)) { /* first call for this one, or data changed size */ mp->m_data = realloc(mp->m_data, mp->m_datalen); if (mp->m_data == NULL) { fprintf(stderr, "Error: %s: buffer alloc failed for sysctl metric \"%s\"\n", mp->m_pcpname, mp->m_name); __pmNoMem("do_sysctl", mp->m_datalen, PM_FATAL_ERR); /*NOTREACHED*/ } } else return -errno; } if (xpect > 0 && mp->m_datalen != xpect) { fprintf(stderr, "Error: %s: sysctl(%s) datalen=%d not %d!\n", mp->m_pcpname, mp->m_name, (int)mp->m_datalen, (int)xpect); return 0; } return mp->m_datalen; }
/* take a pmResult (from a control log request) and half-clone it: return a * pointer to a new pmResult struct which shares the pmValueSets in the * original that have numval > 0, and has null pointers for the pmValueSets * in the original with numval <= 0 */ static pmResult * siamise_request(pmResult *request) { int i, need; pmValueSet *vsp; pmResult *result; need = sizeof(pmResult) + (request->numpmid - 1) * sizeof(pmValueSet *); result = (pmResult *)malloc(need); if (result == NULL) { __pmNoMem("siamise_request: malloc pmResult", need, PM_FATAL_ERR); } for (i = 0; i < request->numpmid; i++) { vsp = request->vset[i]; if (vsp->numval > 0) result->vset[i] = request->vset[i]; else result->vset[i] = NULL; } result->timestamp = request->timestamp; /* structure assignment */ result->numpmid = request->numpmid; return result; }