void init_metadata_iovector(struct trace_mapped_metadata *metadata, trace_pid_t pid) { memset(&metadata->metadata_payload_record, 0, sizeof(metadata->metadata_payload_record)); metadata->metadata_payload_record.rec_type = TRACE_REC_TYPE_METADATA_PAYLOAD; metadata->metadata_payload_record.termination = 0; metadata->metadata_payload_record.pid = pid; size_t remaining_length = metadata->size; size_t num_iovec_pairs = num_metadata_trace_records(remaining_length); metadata->metadata_iovec_len = 2*num_iovec_pairs; metadata->metadata_iovec = malloc((metadata->metadata_iovec_len + 1) * sizeof(struct iovec)); unsigned int i; for (i = 0; i < num_iovec_pairs; i++) { metadata->metadata_iovec[i*2].iov_base = &metadata->metadata_payload_record; metadata->metadata_iovec[i*2].iov_len = TRACE_RECORD_HEADER_SIZE; metadata->metadata_iovec[i*2+1].iov_base = &((char *) metadata->base_address)[i * TRACE_RECORD_PAYLOAD_SIZE]; size_t len = MIN(TRACE_RECORD_PAYLOAD_SIZE, remaining_length); TRACE_ASSERT(len > 0); metadata->metadata_iovec[i*2+1].iov_len = len; remaining_length -= len; } TRACE_ASSERT(remaining_length == 0); if (metadata->metadata_iovec[metadata->metadata_iovec_len - 1].iov_len < TRACE_RECORD_PAYLOAD_SIZE) { static const char zeros[TRACE_RECORD_PAYLOAD_SIZE] = { '\0' }; metadata->metadata_iovec[metadata->metadata_iovec_len].iov_len = TRACE_RECORD_PAYLOAD_SIZE - metadata->metadata_iovec[metadata->metadata_iovec_len - 1].iov_len; metadata->metadata_iovec[metadata->metadata_iovec_len].iov_base = (void *)zeros; metadata->metadata_iovec_len++; } }
bool_t internal_buf_contiguous_pending_read_as_iov(struct trace_internal_buf *buf, struct iovec *iov) { const unsigned num_recs_pending = internal_buf_num_recs_pending(buf); TRACE_ASSERT(buf->read_idx.c < effective_capacity_c(buf)); const bool_t all_pending_flushed = (buf->read_idx.c + num_recs_pending <= effective_capacity_c(buf)); const unsigned len = all_pending_flushed ? num_recs_pending : effective_capacity_c(buf) - buf->read_idx.c; memset(iov, 0, sizeof(*iov)); if (len > 0) { iov->iov_base = buf->records + buf->read_idx.c; iov->iov_len = TRACE_RECORD_SIZE * len; if (INTERNAL_BUF_INVALID_INDEX == buf->write_idx.t) { /* No longer full since we read some records */ buf->write_idx.t = buf->read_idx.t; } /* TODO: Allow adding pending data multiple times, currently we have to commit first. */ buf->read_idx.t = internal_buf_recs_ahead_of_read_c(buf, len); if (index_has_wrapped_around(&buf->read_idx)) { TRACE_ASSERT(0 == buf->read_idx.t); buf->n_slack_recs.t = 0; } } else { TRACE_ASSERT(all_pending_flushed); } return all_pending_flushed; }
/* Returns the exclude state of the object */ uint8_t uiTraceIsObjectExcluded(traceObjectClass objectclass, objectHandleType handle) { TRACE_ASSERT(objectclass < TRACE_NCLASSES, "prvTraceIsObjectExcluded: objectclass >= TRACE_NCLASSES", 1); TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceIsObjectExcluded: Invalid value for handle", 1); switch(objectclass) { case TRACE_CLASS_TASK: return TRACE_GET_TASK_FLAG_ISEXCLUDED(handle); case TRACE_CLASS_SEMAPHORE: return TRACE_GET_SEMAPHORE_FLAG_ISEXCLUDED(handle); case TRACE_CLASS_MUTEX: return TRACE_GET_MUTEX_FLAG_ISEXCLUDED(handle); case TRACE_CLASS_QUEUE: return TRACE_GET_QUEUE_FLAG_ISEXCLUDED(handle); case TRACE_CLASS_TIMER: return TRACE_GET_TIMER_FLAG_ISEXCLUDED(handle); case TRACE_CLASS_EVENTGROUP: return TRACE_GET_EVENTGROUP_FLAG_ISEXCLUDED(handle); } vTraceError("Invalid object class ID in uiTraceIsObjectExcluded!"); /* Must never reach */ return 1; }
uint16_t uiIndexOfObject(objectHandleType objecthandle, uint8_t objectclass) { TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiIndexOfObject: Invalid value for objectclass", 0); TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiIndexOfObject: Invalid value for objecthandle", 0); if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])) { return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1))); } vTraceError("Object table lookup with invalid object handle or object class!"); return 0; }
// ----------------------------------------------------------------------------- // CCDSYFactory::LoadLDSYModuleL // ----------------------------------------------------------------------------- void CCDSYFactory::LoadLDSYModuleL() { COM_TRACE_( "CDSY - CCDSYFactory::LoadLDSYModuleL()" ); RFs fs; RFile file; User::LeaveIfError( fs.Connect() ); CleanupClosePushL( fs ); TInt err = file.Open( fs, KLDSYIniFile, EFileRead ); TRACE_ASSERT( err == KErrNone ); if ( err != KErrNone ) { COM_TRACE_( "CDSY - CCDSYFactory::LoadLDSYModuleL - CommonDSY.ini file missing" ); CleanupStack::PopAndDestroy(); iCDSYDOSServerRequestManager->iLDSYFind = EFalse; } else { CleanupClosePushL( file ); TBuf8<KMaxFileName> rawFileName; User::LeaveIfError( file.Read( rawFileName ) ); CleanupStack::PopAndDestroy( 2 ); HBufC* unicodeFileName = HBufC::NewLC( rawFileName.Length() ); TPtr fileNamePtr( unicodeFileName->Des() ); fileNamePtr.Copy( rawFileName ); TLibraryFunction entryPoint; _LIT(KDSYBinaryLocDrive, "z:"); TBuf<256> dsyBinaryLoc(KDC_SHARED_LIB_DIR); dsyBinaryLoc.Insert(0, KDSYBinaryLocDrive); User::LeaveIfError( iLDSYLibrary.Load( fileNamePtr, dsyBinaryLoc ) ); entryPoint = iLDSYLibrary.Lookup( 1 ); TRACE_ASSERT( entryPoint != NULL ); iDSYServiceLogicFactory = ( MCDSYServiceLogicFactory * )entryPoint(); TRACE_ASSERT( iDSYServiceLogicFactory != NULL ); CleanupStack::PopAndDestroy( unicodeFileName ); COM_TRACE_( "CDSY - CCDSYFactory::LoadLDSYModuleL - return void" ); } }
/** * @brief Closes a socket connection and releases its resources * * @param *sock_cb Socket Control Block which must be closed (#HM_SOCKET_CB) * @return @c void */ void hm_close_sock_connection(HM_SOCKET_CB *sock_cb) { /***************************************************************************/ /* Variable Declarations */ /***************************************************************************/ /***************************************************************************/ /* Sanity Checks */ /***************************************************************************/ TRACE_ENTRY(); TRACE_ASSERT(sock_cb != NULL); /***************************************************************************/ /* Main Routine */ /***************************************************************************/ if(sock_cb->sock_fd > 0) { TRACE_INFO(("Closing socket")); close(sock_cb->sock_fd); sock_cb->sock_fd = -1; } HM_REMOVE_FROM_LIST(sock_cb->node); sock_cb->tprt_cb = NULL; hm_free_sock_cb(sock_cb); sock_cb = NULL; /***************************************************************************/ /* Exit Level Checks */ /***************************************************************************/ TRACE_EXIT(); return; }/* hm_close_sock_connection */
static void fill_compression_remainder_with_pattern(struct trace_internal_buf *buf, size_t compressed_len) { char *const end_p = (char *)(buf->records + buf->write_idx.t); const size_t fill_len = TRACE_RECORD_SIZE * internal_buf_bytes_to_recs(compressed_len) - compressed_len; TRACE_ASSERT(fill_len < TRACE_RECORD_SIZE); memset(end_p - fill_len, 0x69, fill_len); }
int dump_metadata_if_necessary(struct trace_dumper_configuration_s *conf, struct trace_mapped_buffer *mapped_buffer) { if (!mapped_buffer->metadata_dumped) { mapped_buffer->last_metadata_offset = trace_dumper_get_effective_record_file_pos(&conf->record_file); int rc = trace_dump_metadata(conf, &conf->record_file, mapped_buffer); if (0 != rc) { if (!trace_dumper_async_timed_out()) { syslog(LOG_USER|LOG_ERR, "Failed to dump metadata to the file %s due to error: %s", conf->record_file.filename, strerror(errno)); ERR("Error dumping metadata"); mapped_buffer->last_metadata_offset = -1; } return rc; } } mapped_buffer->metadata_dumped = TRUE; if (conf->write_notifications_to_file) { if (!mapped_buffer->notification_metadata_dumped) { TRACE_ASSERT(-1 == conf->notification_file.async_writes->aio_fildes); /* We haven't enabled async here yet */ int rc = trace_dump_metadata(conf, &conf->notification_file, mapped_buffer); if (0 != rc) { syslog(LOG_USER|LOG_ERR, "Failed to dump warnings metadata to the file %s due to error: %s", conf->notification_file.filename, strerror(errno)); ERR("Error dumping metadata"); return rc; } } mapped_buffer->notification_metadata_dumped = TRUE; } return 0; }
// ------------------------------------------------------------------------------- // CBtmcBattery::GoActive // ------------------------------------------------------------------------------- void CBtmcBattery::GoActive() { TRACE_ASSERT(!IsActive(), KErrGeneral); iProperty.Subscribe(iStatus); SetActive(); TRACE_FUNC }
traceLabel prvTraceOpenSymbol(const char* name, traceLabel userEventChannel) { uint16_t result; uint8_t len; uint8_t crc; TRACE_SR_ALLOC_CRITICAL_SECTION(); len = 0; crc = 0; TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceLabel)0); prvTraceGetChecksum(name, &crc, &len); trcCRITICAL_SECTION_BEGIN(); result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel); if (!result) { result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel); } trcCRITICAL_SECTION_END(); return result; }
DECLARE_EXTENSION_LDD() { Kern::Printf( "ISI Router kextldd>" ); DLogicalDevice* device = new DISIDevice; TRACE_ASSERT( device ); Kern::Printf( "ISI Router kextldd 0x%x<", device ); return device; }
// ----------------------------------------------------------------------------- // CTFATestCase::CTFATestCase // ----------------------------------------------------------------------------- EXPORT_C CTFATestCase::CTFATestCase( TInt aCaseId, const TDesC& aName ) : CTFATest( aName ) , iCaseId( aCaseId ) , iTimeout( KDefaultTestTimeout ) { TRACE_ASSERT( aCaseId > 0 ); __ASSERT_ALWAYS( aCaseId > 0, User::Panic( KTFName, ETFPanicInvalidTestCaseNumber ) ); }
static void wait_until_process_exited(pid_t pid, siginfo_t *si) { siginfo_t ignored_si; if (NULL == si) { si = &ignored_si; } memset(si, 0, sizeof(*si)); TRACE_ASSERT(0 == TEMP_FAILURE_RETRY(waitid(P_PID, pid, si, WEXITED))); }
DECLARE_STANDARD_EXTENSION() { Kern::Printf( "ISI Router kext>" ); // Create a container extension DISIRouter* extension = new DISIRouter(); TRACE_ASSERT( extension ); Kern::Printf( "ISI Router kext 0x%x<", extension ); return extension ? KErrNone : KErrNoMemory; }
// ----------------------------------------------------------------------------- // CCDSYFactory::ConstructL // ----------------------------------------------------------------------------- void CCDSYExtensionDOSServerPlugin::ConstructL() { COM_TRACE_( "CDSY - CCDSYExtensionDOSServerPlugin::ConstructL()" ); TCDSYMessage dsyMessage( KCDSYMsgGroup, KCDSYMsgInitializeExtensionCommand, NULL ); iCDSYDOSServerRequestManager.SendMessageL( dsyMessage ); TRACE_ASSERT( dsyMessage.ReturnData() != NULL ); TRACE_ASSERT( dsyMessage.ReturnData()->Length() == sizeof ( TCDSYMsgDataExtensionInitialization ) ); const TCDSYMsgDataExtensionInitialization* returnValue = REINTERPRET_CAST( const TCDSYMsgDataExtensionInitialization*, dsyMessage.ReturnData()->Ptr() ); TRACE_ASSERT( returnValue->iDosExtensionBaseDSY != NULL ); iDosExtensionBaseDSY = returnValue->iDosExtensionBaseDSY; COM_TRACE_( "CDSY - CCDSYExtensionDOSServerPlugin::ConstructL - return void" ); }
void internal_buf_create_iov_for_pending_reads(struct trace_internal_buf *buf, struct iovec iov[2], int *iovcnt) { *iovcnt = 0; const bool_t complete_flush = internal_buf_contiguous_pending_read_as_iov(buf, iov); if (iov[0].iov_len > 0) { ++ *iovcnt; } if (!complete_flush) { const unsigned num_recs_pending = internal_buf_num_recs_pending(buf); TRACE_ASSERT(1 == *iovcnt); iov[1].iov_base = buf->records; iov[1].iov_len = TRACE_RECORD_SIZE * (num_recs_pending - iov[0].iov_len / TRACE_RECORD_SIZE); buf->read_idx.t = internal_buf_recs_ahead_of_read_c(buf, num_recs_pending); ++ *iovcnt; } TRACE_ASSERT(*iovcnt <= 2); }
void CTFDosServerControl::NotifyDosEvent( TInt aEvent, TInt aParameter ) { COMPONENT_TRACE( ( _L( " DSYTESTTOOL - CTFDosServerControl::NotifyDosEvent( %d, %d )" ), aEvent, aParameter ) ); CTFDosServerControlTestCase* testCase = STATIC_CAST( CTFDosServerControlTestCase*, CurrentTestCase() ); TRACE_ASSERT( testCase != NULL ); if ( testCase != NULL ) { testCase->NotifyDosEvent( aEvent, aParameter ); } COMPONENT_TRACE( ( _L( " DSYTESTTOOL - CTFDosServerControl::NotifyDosEvent - return" ) ) ); }
DECLARE_STANDARD_EXTENSION() { Kern::Printf( "ISA Access Extension" ); C_TRACE( ( _T( "DIsaAccessExtension EntryPoint ->" ) ) ); // Create a container extension DIsaAccessExtension* extension = new DIsaAccessExtension(); TRACE_ASSERT( extension ); C_TRACE( ( _T( "DIsaAccessExtension EntryPoint <-" ) ) ); return extension ? KErrNone : KErrNoMemory; }
static ssize_t compress_iov_to_buffer(struct trace_record *target, const struct iovec *iov, int iovcnt) { if (NULL == iov) { errno = EFAULT; return -1; } if (iovcnt < 1) { return 0; } char *src_buf = iov[0].iov_base; size_t input_len = iov[0].iov_len; size_t compressed_length = 0; struct snappy_env env; int rc = snappy_init_env(&env); if (rc < 0) { goto finish; } if (iovcnt > 1) { /* TODO: Snappy should be able to accept an input IOV directly. Since this support is currently broken we use a workaround instead. */ input_len = total_iovec_len(iov, iovcnt); src_buf = malloc(input_len); if ((NULL == src_buf) || (copy_iov_to_buffer(src_buf, iov, iovcnt) != (ssize_t) input_len)) { rc = -errno; goto finish; } } if (input_len > 0) { /* Don't bother compressing trailing padding chars. Those will be re-inserted by the reader. */ input_len -= trace_r_count_chr_occurrences(src_buf + 1, input_len - 1, TRACE_UNUSED_SPACE_FILL_VALUE); rc = snappy_compress(&env, src_buf, input_len, (char *)target, &compressed_length); } finish: snappy_free_env(&env); if (src_buf != iov[0].iov_base) { free(src_buf); } if (0 != rc) { errno = -rc; ERR("Buffer compression failed with err", errno, strerror(errno)); return (ssize_t) -1; } TRACE_ASSERT(((ssize_t) compressed_length > 0) || (0 == input_len)); return (ssize_t) compressed_length; }
static int trace_dump_metadata(struct trace_dumper_configuration_s *conf, struct trace_record_file *record_file, struct trace_mapped_buffer *mapped_buffer) { int rc = open_trace_file_if_necessary(conf); if (0 != rc) { return rc; } if (trace_dumper_wait_record_file_async_io_completion(record_file, TRACE_FOREVER) < 0) { const size_t n_bytes = record_file->async_writes->aio_nbytes; const off64_t offset = record_file->async_writes->aio_offset; if (trace_dumper_async_timed_out()) { DEBUG("Metadata dumping deferred due to", n_bytes, "previous data pending async write at ", offset, "for the file", record_file->filename, strerror(errno)); } else { ERR("Delayed write of ", n_bytes, "failed at", offset, "with err", errno, strerror(errno)); } return -1; } if (trace_dumper_net_num_records_pending(record_file) > 0) { DEBUG("Metadata dumping deferred because the internal buffer is not fully flushed for the file", record_file->filename); errno = EAGAIN; return -1; } mapped_buffer->metadata.metadata_payload_record.ts = trace_get_nsec(); /* TODO: write a validator for metadata. */ record_file->post_write_validator = NULL; /* TODO: Introduce rollback logic, like we have for regular data writes */ rc = write_metadata_header_start(conf, record_file, mapped_buffer); if (0 != rc) { return -1; } if (mapped_buffer->metadata.metadata_iovec_len > 0) { TRACE_ASSERT(NULL != mapped_buffer->metadata.metadata_iovec); rc = trace_dumper_write(conf, record_file, mapped_buffer->metadata.metadata_iovec, mapped_buffer->metadata.metadata_iovec_len); if ((size_t) rc != (mapped_buffer->metadata.metadata_iovec_len / 2) * sizeof(struct trace_record)) { if (0 == errno) { errno = EIO; } return -1; } } else { syslog(LOG_USER|LOG_WARNING, "Trace dumper could not dump metadata for the process %s (pid %u) because it has length 0", mapped_buffer->name, mapped_buffer->pid); } return write_metadata_end(conf, record_file, mapped_buffer); }
static void compactify_buffer(struct trace_internal_buf *buf, unsigned start_idx, unsigned actually_used) { TRACE_ASSERT(buf->write_idx.t >= start_idx + actually_used); if ((0 == start_idx) && (buf->n_slack_recs.t >= actually_used)) { DEBUG("Copying", actually_used, "records into slack space", buf->write_idx.t, buf->n_slack_recs.t); memcpy(buf->records + effective_capacity_t(buf), buf->records, TRACE_RECORD_SIZE * actually_used); buf->n_slack_recs.t -= actually_used; buf->write_idx.t = effective_capacity_t(buf); } else { buf->write_idx.t = start_idx + actually_used; } }
int internal_buf_free(struct trace_internal_buf *buf) { if (NULL != buf) { const size_t len = TRACE_RECORD_SIZE * buf->n_recs + BUF_HEADER_SIZE; TRACE_ASSERT(trace_round_size_up_to_page_size(len) == len); if (munmap(buf, len) != 0) { return -1; } } return 0; }
objectHandleType xTraceGetObjectHandle(traceObjectClass objectclass) { objectHandleType handle; static int indexOfHandle; TRACE_ASSERT(objectclass < TRACE_NCLASSES, "xTraceGetObjectHandle: Invalid value for objectclass", (objectHandleType)0); indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; if (objectHandleStacks.objectHandles[indexOfHandle] == 0) { /* Zero is used to indicate a never before used handle, i.e., new slots in the handle stack. The handle slot needs to be initialized here (starts at 1). */ objectHandleStacks.objectHandles[indexOfHandle] = (objectHandleType)(1 + indexOfHandle - objectHandleStacks.lowestIndexOfClass[objectclass]); } handle = objectHandleStacks.objectHandles[indexOfHandle]; if (objectHandleStacks.indexOfNextAvailableHandle[objectclass] > objectHandleStacks.highestIndexOfClass[objectclass]) { /* ERROR */ vTraceError(pszTraceGetErrorNotEnoughHandles(objectclass)); handle = 0; /* an invalid/anonymous handle - but the recorder is stopped now... */ } else { int hndCount; objectHandleStacks.indexOfNextAvailableHandle[objectclass]++; hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] - objectHandleStacks.lowestIndexOfClass[objectclass]; if (hndCount > objectHandleStacks.handleCountWaterMarksOfClass[objectclass]) { objectHandleStacks.handleCountWaterMarksOfClass[objectclass] = (objectHandleType)hndCount; } TRACE_CLEAR_OBJECT_FLAG_ISEXCLUDED(objectclass, handle); } return handle; }
// ----------------------------------------------------------------------------- // CCDSYExtensionDOSServerPlugin::CallFunctionAndCompleteL // ----------------------------------------------------------------------------- void CCDSYExtensionDOSServerPlugin::CallFunctionAndCompleteL( TInt aFunc, TAny* aParameter, TInt aParLength, const RMessage2& aMessage ) { API_TRACE_4( "CDSY - CCDSYExtensionDOSServerPlugin::CallFunctionAndCompleteL(0x%x, 0x%x, 0x%x, 0x%x)", aFunc, aParameter, aParLength, &aMessage ); TRACE_ASSERT( iDosExtensionBaseDSY != NULL ); if ( iDosExtensionBaseDSY == NULL ) { User::Leave( KErrGeneral ); } iDosExtensionBaseDSY->CallFunctionAndCompleteL( aFunc, aParameter, aParLength, aMessage ); API_TRACE_( "CDSY - CCDSYExtensionDOSServerPlugin::CallFunctionAndCompleteL - return void" ); }
// ----------------------------------------------------------------------------- // CCDSYExtensionDOSServerPlugin::CallFunctionL // ----------------------------------------------------------------------------- TInt CCDSYExtensionDOSServerPlugin::CallFunctionL( TInt aFunc, TAny* aParameter, TInt aParLength, TBool& aParameterModified ) { API_TRACE_4( "CDSY - CCDSYExtensionDOSServerPlugin::CallFunctionL(0x%x, 0x%x, 0x%x, 0x%x)", aFunc, aParameter, aParLength, &aParameterModified ); TRACE_ASSERT( iDosExtensionBaseDSY != NULL ); if ( iDosExtensionBaseDSY == NULL ) { User::Leave( KErrGeneral ); } TInt err = iDosExtensionBaseDSY->CallFunctionL( aFunc, aParameter, aParLength, aParameterModified ); API_TRACE_1( "CDSY - CCDSYExtensionDOSServerPlugin::CallFunctionL - return 0x%x", err ); return err; }
bool_t trace_process_exists(pid_t pid) { const int saved_errno = errno; if (0 == kill(pid, 0)) { return TRUE; } switch (errno) { case EPERM: errno = saved_errno; return TRUE; case ESRCH: errno = saved_errno; break; default: TRACE_ASSERT(EINVAL != errno); break; } return FALSE; }
static pid_t get_proc_ppid(pid_t pid) { char name[NAME_MAX + 10]; TRACE_ASSERT(sprintf(name, "/proc/%d/stat", (int) pid) > 0); FILE *const fp = fopen(name, "rt"); if (NULL == fp) { set_esrch_if_necessary(); return -1; } static const char fmt[] = "%d %s %c %d"; pid_t reported_pid = -1, ppid = -1; char state; if ((fscanf(fp, fmt, &reported_pid, name, &state, &ppid) != 4) || (reported_pid != pid)) { errno = EPROTO; ppid = -1; } fclose(fp); return ppid; }
/** * @brief Closes connection on the given transport CB * * @param *tprt_cb Transport Control Block whose connection is to be closed (#HM_TRANSPORT_CB) * @return #HM_OK if successful, else #HM_ERR */ int32_t hm_tprt_close_connection(HM_TRANSPORT_CB *tprt_cb) { /***************************************************************************/ /* Variable Declarations */ /***************************************************************************/ int32_t ret_val = HM_OK; HM_MSG *msg = NULL; HM_LIST_BLOCK *block = NULL; /***************************************************************************/ /* Sanity Checks */ /***************************************************************************/ TRACE_ENTRY(); TRACE_ASSERT(tprt_cb != NULL); /***************************************************************************/ /* Main Routine */ /***************************************************************************/ /***************************************************************************/ /* Empty the outgoing buffers queue. Don't try to send them, just drop. */ /***************************************************************************/ TRACE_DETAIL(("Emptying pending queue.")); for(block = (HM_LIST_BLOCK *)HM_NEXT_IN_LIST(tprt_cb->pending); block != NULL; block = (HM_LIST_BLOCK *)HM_NEXT_IN_LIST(tprt_cb->pending)) { msg = (HM_MSG *)block->target; /***************************************************************************/ /* Remove from list. */ /***************************************************************************/ HM_REMOVE_FROM_LIST(block->node); TRACE_DETAIL(("Freeing Message!")); hm_free_buffer(msg); free(block); block = NULL; } if(tprt_cb->in_buffer != NULL) { TRACE_DETAIL(("Transport has data in its input buffers. Freeing!")); hm_free_buffer((HM_MSG *)tprt_cb->in_buffer); tprt_cb->in_buffer = NULL; } /***************************************************************************/ /* Transport Types may differ. Default is Socket Based Transport. So, we're*/ /* currently only implementing the default case. */ /***************************************************************************/ switch(tprt_cb->type) { default: /***************************************************************************/ /* It is possible that the socket connection was torn down before, or never*/ /* existed in the first place. */ /***************************************************************************/ if(tprt_cb->sock_cb != NULL) { TRACE_DETAIL(("Closing socket connections")); hm_close_sock_connection(tprt_cb->sock_cb); tprt_cb->sock_cb = NULL; } } /***************************************************************************/ /* Exit Level Checks */ /***************************************************************************/ TRACE_EXIT(); return(ret_val); }/* hm_tprt_close_connection */
void CBtmActive::GoActive() { TRACE_ASSERT(!IsActive(), EBTPanicRequestOutstanding); SetActive(); TRACE_FUNC }
pid_t trace_fork_with_child_init( int (*child_init)(void), int (*cleanup_on_failure)(pid_t child_pid) ) { /* In order to guarantee that either success or failure is returned consistently in both the parent and the child we follow this procedure: * - The parent creates a pipe * - The parent forks * - The child calls the supplied child_init function. * - The child sends either 0 (if successful) or otherwise the errno value via the pipe. In case of failure it exits. * - If the child failed to send a completion status via the pipe or reported an error, the parent waits for it to exit. * */ int pipefd[2]; if (pipe(pipefd) < 0) { return -1; } int status = 0; const pid_t pid = fork(); if (pid < 0) { status = errno; } else if (0 == pid) { /* Child */ if (child_init() < 0) { status = errno; TRACE_ASSERT(0 != status); } switch (write(pipefd[1], &status, sizeof(status))) { case sizeof(status): break; default: errno = EIO; /* no break - fall through to the regular error case */ case -1: if (0 == status) { status = errno; } TRACE_ASSERT(0 != status); break; } if (0 != status) { cleanup_on_failure(getpid()); _exit(MIN(status, 0xFF)); } } else { /* Parent */ TRACE_ASSERT(pid > 0); const ssize_t n_bytes_read = read(pipefd[0], &status, sizeof(status)); switch (n_bytes_read) { case sizeof(status): if (0 != status) { wait_until_process_exited(pid, NULL); } break; case 0: { /* The child process exited without writing a status to the pipe. */ siginfo_t si; wait_until_process_exited(pid, &si); if (CLD_EXITED == si.si_code) { status = (0 != si.si_status) ? si.si_status : EIO; } else { cleanup_on_failure(pid); /* The child most likely was killed by a signal, so clean after it. */ status = EIO; } TRACE_ASSERT(0 != status); break; } default: /* Something went badly wrong with the pipe */ status = (n_bytes_read < 0) ? errno : EIO; if (0 == kill(pid, SIGKILL)) { wait_until_process_exited(pid, NULL); cleanup_on_failure(pid); } break; } } close(pipefd[0]); close(pipefd[1]); if (0 != status) { errno = status; return -1; } return pid; }