/** * Returns a new multicast receiver. * * @param[out] receiver Pointer to returned receiver. * @param[in] tcpAddr Address of the TCP server from which to * retrieve missed data-blocks. May be hostname or * IP address. * @param[in] tcpPort Port number of the TCP server to which to * connect. * @param[in] bof_func Function to call when the multicast layer has * seen a beginning-of-file. * @param[in] eof_func Function to call when the multicast layer has * completely received a file. * @param[in] missed_file_func Function to call when a file is missed by the * multicast layer. * @param[in] mcastAddr Address of the multicast group to receive. May * be groupname or formatted IP address. * @param[in] mcastPort Port number of the multicast group. * @param[in] obj Relevant object in the receiving application to * pass to the above functions. May be NULL. * @retval 0 Success. The client should call \c * mcastReceiver_free(*receiver) when the * receiver is no longer needed. * @retval EINVAL if @code{0==buf_func || 0==eof_func || * 0==missed_file_func || 0==addr} or the * multicast group address couldn't be converted * into a binary IP address. * @retval ENOMEM Out of memory. \c log_add() called. * @retval -1 Other failure. \c log_add() called. */ int mcastReceiver_new( McastReceiver** const receiver, const char* const tcpAddr, const unsigned short tcpPort, const BofFunc bof_func, const EofFunc eof_func, const MissedFileFunc missed_file_func, const char* const mcastAddr, const unsigned short mcastPort, void* const obj) { McastReceiver* rcvr = (McastReceiver*)LOG_MALLOC(sizeof(McastReceiver), "multicast receiver"); if (0 == rcvr) return ENOMEM; try { mcastReceiver_init(rcvr, tcpAddr, tcpPort, bof_func, eof_func, missed_file_func, mcastAddr, mcastPort, obj); *receiver = rcvr; return 0; } catch (const std::invalid_argument& e) { log_add("%s", e.what()); free(rcvr); return EINVAL; } catch (const std::exception& e) { log_add("%s", e.what()); free(rcvr); return -1; } }
/** * Creates a new section 1 in a \c gribfield structure from a decoded GRIB-2 * field. * * Atomic, * Idempotent, * Thread-safe * * @param[out] gfld Pointer to the \c gribfield structure. Client should call * \c sec1_free(gfld) when the section 1 data is no longer * needed. * @param[in] field Pointer to the decoded GRIB-2 field. * @retval 0 Success. \c gfld->idsect and \c gfld->idsectlen are set. * @retval 1 Corrupt GRIB-2 message. * @retval 3 System error. */ static int sec1_new( gribfield* const gfld, Grib2Field* const field) { /** * Location and length of encoded section 1 parameters. */ static ParamInfo paramInfo[] = { { 5, 2}, { 7, 2}, { 9, 1}, {10, 1}, {11, 1}, {12, 2}, {14, 1}, {15, 1}, {16, 1}, {17, 1}, {18, 1}, {19, 1}, {20, 1} }; static unsigned numParams = sizeof(paramInfo)/sizeof(paramInfo[0]); Grib2Section* sec1; g2int* params = (g2int*)LOG_MALLOC(numParams*sizeof(g2int), "section 1 parameter array"); int status; if (NULL == params) return 3; /* System error */ (void)g2f_getSection(field, 1, &sec1); if (status = getG2intParams(sec1, paramInfo, numParams, params)) { free(params); return status; } gfld->idsect = params; gfld->idsectlen = numParams; return 0; }
/** * Consolidates the contents of the product-index map into one contiguous * segment. * * @param[in] max Maximum number of signatures in the file. * @retval 0 Success. * @retval LDM7_SYSTEM System error. `log_add()` called. */ static Ldm7Status consolidateMap( const size_t max) { /* * In general, the signatures in the circular buffer will be in two * contiguous segments: a "new" segment and an "old" segment. The "new" * segment comprises the more recent signatures from the beginning of the * buffer to just before `oldSeg`; the "old" segment comprises the older * signatures from `oldSeg` to the end of the buffer. This function * consolidates the two segments into one contiguous segment with the oldest * signature at the beginning of the buffer. */ int status; const size_t newCount = mmo->oldSig; const size_t oldCount = mmo->numSigs < max ? mmo->numSigs // buffer isn't full : mmo->numSigs - mmo->oldSig; size_t smallBytes, bigBytes; void *smallSeg, *bigSeg, *newBigSeg, *newSmallSeg; if (newCount >= oldCount) { bigBytes = newCount * SIG_SIZE; smallBytes = oldCount * SIG_SIZE; smallSeg = mmo->sigs + newCount; bigSeg = mmo->sigs; newBigSeg = mmo->sigs + oldCount; newSmallSeg = mmo->sigs; } else { bigBytes = oldCount * SIG_SIZE; smallBytes = newCount * SIG_SIZE; smallSeg = mmo->sigs; bigSeg = mmo->sigs + newCount; newBigSeg = mmo->sigs; newSmallSeg = mmo->sigs + oldCount; } signaturet* tmpSigs = LOG_MALLOC(smallBytes, "temporary signatures buffer"); if (NULL == tmpSigs) { status = LDM7_SYSTEM; } else { sigset_t saveSet; (void)memcpy(tmpSigs, smallSeg, smallBytes); // copy segment (void)memmove(newBigSeg, bigSeg, bigBytes); // shift other segment (void)memcpy(newSmallSeg, tmpSigs, smallBytes); // restore segment mmo->oldSig = 0; free(tmpSigs); maxSigs = max; status = 0; } return status; }
int iniche_create_log(log_data_t **p, int log_level, char *fname, void *pio) { int i; /* This routine assumes a NULL pointer is passed */ if(*p == NULL) { *p = (log_data_t *) LOG_MALLOC(sizeof(log_data_t)); if(*p == NULL) { return(-1); } memset(*p, 0, sizeof(log_data_t)); } else { for(i = 0; i < LOG_TYPE_MAX_NUM; i++) { (*p)->log_counts[i] = 0; } } if((log_level >= LOG_TYPE_NONE) && (log_level < LOG_TYPE_MAX_NUM)) { (*p)->log_level = log_level; } else { (*p)->log_level = DEFAULT_LOG_LEVEL; } #ifdef USE_LOGFILE if(fname) { strcpy((*p)->log_fname, fname); } else { strcpy((*p)->log_fname, LOG_FILE_DEFAULT); } if((*p)->log_fp) { nv_fclose((*p)->log_fp); (*p)->log_fp = NULL; } (*p)->log_fp = nv_fopen((*p)->log_fname, "w"); if((*p)->log_fp == NULL) { iniche_free_log(p); return(-1); } #endif (*p)->pio = pio; return(0); }
/** * Returns a new entry. * * @param[in] iProd Index of the product. * @retval NULL Error. \c log_add() called. * @return Pointer to the new entry. The client should call \c * entry_free() when it is no longer needed. */ static Entry* entry_new( const McastProdIndex iProd) { Entry* entry = LOG_MALLOC(sizeof(Entry), "product-index queue-entry"); if (entry) { entry->iProd = iProd; entry->prev = entry->next = NULL; } return entry; }
/** * Returns a new server contact information object. * * @param[in] id Name or formatted IP address of the host running the server. * @param[in] port Port number of the server. * @retval NULL Error. \c log_add() called. * @return Pointer to a new server contact information object. The * client should call \c serverInfo_free() when it is no longer * needed. */ ServerInfo* serverInfo_new( const char* const id, const unsigned short port) { ServerInfo* si = LOG_MALLOC(sizeof(ServerInfo), "server contact information"); if (si) { si->id = strdup(id); if (!si->id) { LOG_ADD1("Couldn't duplicate server identifier \"%s\"", id); free(si); si = NULL; } else { si->port = port; } } return si; }
/** * Returns a new \c gribfield structure initialized from a field in a GRIB * message. * * @param[out] gribField Address of pointer to \c gribfield structure. Client * should call \c gfld_free(*gribField) when the * structure is no longer needed. * @param[in] field Pointer to field in a GRIB message. * @param[in] index 0-based index of the field in the GRIB message. * @retval 0 Success. \c *gribField is set. * @retval 1 System error. */ static int gfld_new( gribfield** const gribField, Grib2Field* const field, const unsigned index) { static char g2tables[5][LLMXLN]; static char* tbllist[5] = {g2tables[0], g2tables[1], g2tables[2], g2tables[3], g2tables[4]}; int status; const gribfield* gfld = (gribfield*)LOG_MALLOC(sizeof(gribfield), "GRIB field"); if (NULL == gfld) { status = 1; } else { if (status = gfld_init(gfld, field, index)) free(gfld); else *gribField = gfld; } return status; }
int glog_app(void * pio) { int i; char *buf; buf = (char *) ((GEN_IO)pio)->inbuf; ns_printf(pio,"%s\n", buf); if(p_global_log == NULL) { p_global_log = (log_data_t *) LOG_MALLOC(sizeof(log_data_t)); if(p_global_log == NULL) { ns_printf(pio,"glog_app: LOG_MALLOC() failed\n"); return(-1); } memset(p_global_log, 0, sizeof(log_data_t)); p_global_log->log_level = DEFAULT_LOG_LEVEL; #ifdef USE_LOGFILE strcpy(p_global_log->log_fname, LOG_FILE_DEFAULT); #endif } if(p_global_log->argv) { LOG_FREE(p_global_log->argv); p_global_log->argv = NULL; } p_global_log->argv = parse_args(buf, GLOG_MAX_ARGC, &(p_global_log->argc)); if(p_global_log->argv == NULL) { ns_printf(pio, "parse_args() failed for %s\n", buf); return(-1); } #if 0 for(i = 0; i < p_global_log->argc; i++) { ns_printf(pio, "%s ", p_global_log->argv[i]); } ns_printf(pio,"\n"); #endif if(glog_process_args(p_global_log)) { ns_printf(pio, "glog_process_args() failed\n"); return(-1); } /* Here now we can configure our log app */ if(p_global_log->stop_flag) { glog_with_type(LOG_TYPE_INFO, "INICHE LOG stopped", 1); iniche_free_log(&p_global_log); return(0); } if(p_global_log->start_flag) { #ifdef USE_LOGFILE if(iniche_create_log(&p_global_log, p_global_log->log_level, p_global_log->log_fname, pio)) #else if(iniche_create_log(&p_global_log, p_global_log->log_level, NULL, pio)) #endif { ns_printf(pio,"iniche_create_log() failed\n"); } else { ns_printf(pio,"starting glog:\n"); glog_with_type(LOG_TYPE_INFO, "INICHE LOG initialized", 1); } p_global_log->start_flag = 0; } return 0; }
XPT_ArenaMalloc(XPTArena *arena, size_t size) { uint8_t *cur; size_t bytes; if (!size) return NULL; if (!arena) { XPT_ASSERT(0); return NULL; } bytes = ALIGN_RND(size, arena->alignment); LOG_MALLOC(arena, size, bytes); if (bytes > arena->space) { BLK_HDR* new_block; size_t block_header_size = ALIGN_RND(sizeof(BLK_HDR), arena->alignment); size_t new_space = arena->block_size; while (bytes > new_space - block_header_size) new_space += arena->block_size; new_block = (BLK_HDR*) calloc(new_space/arena->alignment, arena->alignment); if (!new_block) { arena->next = NULL; arena->space = 0; return NULL; } LOG_REAL_MALLOC(arena, new_space); /* link block into the list of blocks for use when we destroy */ new_block->next = arena->first; arena->first = new_block; /* save other block header info */ new_block->size = new_space; /* set info for current block */ arena->next = ((uint8_t*)new_block) + block_header_size; arena->space = new_space - block_header_size; #ifdef DEBUG /* mark block for corruption check */ memset(arena->next, 0xcd, arena->space); #endif } #ifdef DEBUG { /* do corruption check */ size_t i; for (i = 0; i < bytes; ++i) { XPT_ASSERT(arena->next[i] == 0xcd); } /* we guarantee that the block will be filled with zeros */ memset(arena->next, 0, bytes); } #endif cur = arena->next; arena->next += bytes; arena->space -= bytes; return cur; }
* @param[out] nbytes The number of bytes that would be written to the * buffer -- excluding the terminating NUL character -- * if it was sufficiently capacious. * @retval NULL Error. `log_start()` called. * @return Pointer to the NUL-terminated string buffer containing * the formatted arguments. The caller should free when * it's no longer needed. */ static char* tryFormat( const size_t size, const char* const restrict fmt, va_list args, int* const restrict nbytes) { char* buf = LOG_MALLOC(size, "formatting buffer"); if (buf) *nbytes = vsnprintf(buf, size, fmt, args); return buf; } /** * Returns formatted arguments. * * @param[in] initSize The initial size of the formatting buffer, including the * terminating NUL character. * @param[in] fmt The format for the arguments. * @param[in] args The arguments to be formatted. Must have been * initialized by `va_start()` or `va_copy()`.