/*PAGE * * daemon * * This task runs forever. It waits for service requests on the FTP port * (port 21 by default). When a request is received, it opens a new session * to handle those requests until the connection is closed. * * Input parameters: * NONE * * Output parameters: * NONE */ static void daemon(rtems_task_argument args __attribute__((unused))) { int s; socklen_t addrLen; struct sockaddr_in addr; FTPD_SessionInfo_t *info = NULL; s = socket(PF_INET, SOCK_STREAM, 0); if (s < 0) syslog(LOG_ERR, "ftpd: Error creating socket: %s", serr()); addr.sin_family = AF_INET; addr.sin_port = htons(rtems_ftpd_configuration.port); addr.sin_addr.s_addr = htonl(INADDR_ANY); memset(addr.sin_zero, 0, sizeof(addr.sin_zero)); if (0 > bind(s, (struct sockaddr *)&addr, sizeof(addr))) syslog(LOG_ERR, "ftpd: Error binding control socket: %s", serr()); else if (0 > listen(s, 1)) syslog(LOG_ERR, "ftpd: Error listening on control socket: %s", serr()); else while (1) { int ss; addrLen = sizeof(addr); ss = accept(s, (struct sockaddr *)&addr, &addrLen); if (0 > ss) syslog(LOG_ERR, "ftpd: Error accepting control connection: %s", serr()); else if(!set_socket_timeout(ss, ftpd_timeout)) close_socket(ss); else { info = task_pool_obtain(); if (NULL == info) { close_socket(ss); } else { info->ctrl_socket = ss; if ((info->ctrl_fp = fdopen(info->ctrl_socket, "r+")) == NULL) { syslog(LOG_ERR, "ftpd: fdopen() on socket failed: %s", serr()); close_stream(info); task_pool_release(info); } else { /* Initialize corresponding SessionInfo structure */ info->def_addr = addr; if(0 > getsockname(ss, (struct sockaddr *)&addr, &addrLen)) { syslog(LOG_ERR, "ftpd: getsockname(): %s", serr()); close_stream(info); task_pool_release(info); } else { info->use_default = 1; info->ctrl_addr = addr; info->pasv_socket = -1; info->data_socket = -1; info->xfer_mode = TYPE_A; info->data_addr.sin_port = htons(ntohs(info->ctrl_addr.sin_port) - 1); info->idle = ftpd_timeout; /* Wakeup the session task. The task will call task_pool_release after it closes connection. */ rtems_event_send(info->tid, FTPD_RTEMS_EVENT); } } } } } rtems_task_delete(RTEMS_SELF); }
int board_app_initialize(uintptr_t arg) { #ifdef HAVE_RTC_DRIVER FAR struct rtc_lowerhalf_s *rtclower; #endif #ifdef CONFIG_SENSORS_QENCODER int index; char buf[9]; #endif int ret; (void)ret; #ifdef HAVE_PROC /* Mount the proc filesystem */ syslog(LOG_INFO, "Mounting procfs to /proc\n"); ret = mount(NULL, CONFIG_NSH_PROC_MOUNTPOINT, "procfs", 0, NULL); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to mount the PROC filesystem: %d (%d)\n", ret, errno); return ret; } #endif #if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) /* Register the LED driver */ ret = userled_lower_initialize(LED_DRIVER_PATH); if (ret < 0) { syslog(LOG_ERR, "ERROR: userled_lower_initialize() failed: %d\n", ret); } #endif #ifdef HAVE_RTC_DRIVER /* Instantiate the STM32L4 lower-half RTC driver */ rtclower = stm32l4_rtc_lowerhalf(); if (!rtclower) { serr("ERROR: Failed to instantiate the RTC lower-half driver\n"); return -ENOMEM; } else { /* Bind the lower half driver and register the combined RTC driver * as /dev/rtc0 */ ret = rtc_initialize(0, rtclower); if (ret < 0) { serr("ERROR: Failed to bind/register the RTC driver: %d\n", ret); return ret; } } #endif #ifdef HAVE_MMCSD /* First, get an instance of the SDIO interface */ g_sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO); if (!g_sdio) { syslog(LOG_ERR, "ERROR: Failed to initialize SDIO slot %d\n", CONFIG_NSH_MMCSDSLOTNO); return -ENODEV; } /* Now bind the SDIO interface to the MMC/SD driver */ ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, g_sdio); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); return ret; } /* Then let's guess and say that there is a card in the slot. There is no * card detect GPIO. */ sdio_mediachange(g_sdio, true); syslog(LOG_INFO, "[boot] Initialized SDIO\n"); #endif #ifdef CONFIG_PWM /* Initialize PWM and register the PWM device. */ ret = stm32l4_pwm_setup(); if (ret < 0) { syslog(LOG_ERR, "ERROR: stm32l4_pwm_setup() failed: %d\n", ret); } #endif #ifdef CONFIG_ADC /* Initialize ADC and register the ADC driver. */ ret = stm32l4_adc_setup(); if (ret < 0) { syslog(LOG_ERR, "ERROR: stm32l4_adc_setup failed: %d\n", ret); } #endif #ifdef CONFIG_TIMER /* Initialize and register the timer driver */ ret = board_timer_driver_initialize("/dev/timer0", 2); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the timer driver: %d\n", ret); return ret; } #endif #ifdef CONFIG_SENSORS_QENCODER /* Initialize and register the qencoder driver */ index = 0; #ifdef CONFIG_STM32L4_TIM1_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 1); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #ifdef CONFIG_STM32L4_TIM2_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 2); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #ifdef CONFIG_STM32L4_TIM3_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 3); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #ifdef CONFIG_STM32L4_TIM4_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 4); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #ifdef CONFIG_STM32L4_TIM5_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 5); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #ifdef CONFIG_STM32L4_TIM8_QE sprintf(buf, "/dev/qe%d", index++); ret = stm32l4_qencoder_initialize(buf, 8); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the qencoder: %d\n", ret); return ret; } #endif #endif UNUSED(ret); return OK; }
int task_spawn(FAR pid_t *pid, FAR const char *name, main_t entry, FAR const posix_spawn_file_actions_t *file_actions, FAR const posix_spawnattr_t *attr, FAR char *const argv[], FAR char *const envp[]) { struct sched_param param; pid_t proxy; #ifdef CONFIG_SCHED_WAITPID int status; #endif int ret; sinfo("pid=%p name=%s entry=%p file_actions=%p attr=%p argv=%p\n", pid, name, entry, file_actions, attr, argv); /* If there are no file actions to be performed and there is no change to * the signal mask, then start the new child task directly from the parent task. */ #ifndef CONFIG_DISABLE_SIGNALS if ((file_actions == NULL || *file_actions == NULL) && (attr == NULL || (attr->flags & POSIX_SPAWN_SETSIGMASK) == 0)) #else if (file_actions == NULL || *file_actions == NULL) #endif { return task_spawn_exec(pid, name, entry, attr, argv); } /* Otherwise, we will have to go through an intermediary/proxy task in order * to perform the I/O redirection. This would be a natural place to fork(). * However, true fork() behavior requires an MMU and most implementations * of vfork() are not capable of these operations. * * Even without fork(), we can still do the job, but parameter passing is * messier. Unfortunately, there is no (clean) way to pass binary values * as a task parameter, so we will use a semaphore-protected global * structure. */ /* Get exclusive access to the global parameter structure */ spawn_semtake(&g_spawn_parmsem); /* Populate the parameter structure */ g_spawn_parms.result = ENOSYS; g_spawn_parms.pid = pid; g_spawn_parms.file_actions = file_actions ? *file_actions : NULL; g_spawn_parms.attr = attr; g_spawn_parms.argv = argv; g_spawn_parms.u.task.name = name; g_spawn_parms.u.task.entry = entry; /* Get the priority of this (parent) task */ ret = sched_getparam(0, ¶m); if (ret < 0) { int errcode = get_errno(); serr("ERROR: sched_getparam failed: %d\n", errcode); spawn_semgive(&g_spawn_parmsem); return errcode; } /* Disable pre-emption so that the proxy does not run until waitpid * is called. This is probably unnecessary since the task_spawn_proxy has * the same priority as this thread; it should be schedule behind this * task in the ready-to-run list. */ #ifdef CONFIG_SCHED_WAITPID sched_lock(); #endif /* Start the intermediary/proxy task at the same priority as the parent * task. */ proxy = task_create("task_spawn_proxy", param.sched_priority, CONFIG_POSIX_SPAWN_PROXY_STACKSIZE, (main_t)task_spawn_proxy, (FAR char * const *)NULL); if (proxy < 0) { ret = get_errno(); serr("ERROR: Failed to start task_spawn_proxy: %d\n", ret); goto errout_with_lock; } /* Wait for the proxy to complete its job */ #ifdef CONFIG_SCHED_WAITPID ret = waitpid(proxy, &status, 0); if (ret < 0) { serr("ERROR: waitpid() failed: %d\n", errno); goto errout_with_lock; } #else spawn_semtake(&g_spawn_execsem); #endif /* Get the result and relinquish our access to the parameter structure */ ret = g_spawn_parms.result; errout_with_lock: #ifdef CONFIG_SCHED_WAITPID sched_unlock(); #endif spawn_semgive(&g_spawn_parmsem); return ret; }
static int task_spawn_exec(FAR pid_t *pidp, FAR const char *name, main_t entry, FAR const posix_spawnattr_t *attr, FAR char * const *argv) { size_t stacksize; int priority; int pid; int ret = OK; /* Disable pre-emption so that we can modify the task parameters after * we start the new task; the new task will not actually begin execution * until we re-enable pre-emption. */ sched_lock(); /* Use the default task priority and stack size if no attributes are provided */ if (attr) { priority = attr->priority; stacksize = attr->stacksize; } else { struct sched_param param; /* Set the default priority to the same priority as this task */ ret = sched_getparam(0, ¶m); if (ret < 0) { goto errout; } priority = param.sched_priority; stacksize = CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE; } /* Start the task */ pid = task_create(name, priority, stacksize, entry, argv); if (pid < 0) { ret = get_errno(); serr("ERROR: task_create failed: %d\n", ret); goto errout; } /* Return the task ID to the caller */ if (pid) { *pidp = pid; } /* Now set the attributes. Note that we ignore all of the return values * here because we have already successfully started the task. If we * return an error value, then we would also have to stop the task. */ if (attr) { (void)spawn_execattrs(pid, attr); } /* Re-enable pre-emption and return */ errout: sched_unlock(); return ret; }
nsresult nsExpatDriver::HandleError() { PRInt32 code = XML_GetErrorCode(mExpatParser); NS_ASSERTION(code > XML_ERROR_NONE, "unexpected XML error code"); // Map Expat error code to an error string // XXX Deal with error returns. nsAutoString description; nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES, code, description); if (code == XML_ERROR_TAG_MISMATCH) { /** * Expat can send the following: * localName * namespaceURI<separator>localName * namespaceURI<separator>localName<separator>prefix * * and we use 0xFFFF for the <separator>. * */ const PRUnichar *mismatch = MOZ_XML_GetMismatchedTag(mExpatParser); const PRUnichar *uriEnd = nsnull; const PRUnichar *nameEnd = nsnull; const PRUnichar *pos; for (pos = mismatch; *pos; ++pos) { if (*pos == kExpatSeparatorChar) { if (uriEnd) { nameEnd = pos; } else { uriEnd = pos; } } } nsAutoString tagName; if (uriEnd && nameEnd) { // We have a prefix. tagName.Append(nameEnd + 1, pos - nameEnd - 1); tagName.Append(PRUnichar(':')); } const PRUnichar *nameStart = uriEnd ? uriEnd + 1 : mismatch; tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart); nsAutoString msg; nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES, "Expected", msg); // . Expected: </%S>. PRUnichar *message = nsTextFormatter::smprintf(msg.get(), tagName.get()); if (!message) { return NS_ERROR_OUT_OF_MEMORY; } description.Append(message); nsTextFormatter::smprintf_free(message); } // Adjust the column number so that it is one based rather than zero based. PRUint32 colNumber = XML_GetCurrentColumnNumber(mExpatParser) + 1; PRUint32 lineNumber = XML_GetCurrentLineNumber(mExpatParser); nsAutoString errorText; CreateErrorText(description.get(), XML_GetBase(mExpatParser), lineNumber, colNumber, errorText); NS_ASSERTION(mSink, "no sink?"); nsAutoString sourceText(mLastLine); AppendErrorPointer(colNumber, mLastLine.get(), sourceText); // Try to create and initialize the script error. nsCOMPtr<nsIScriptError> serr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); nsresult rv = NS_ERROR_FAILURE; if (serr) { nsCOMPtr<nsIScriptError2> serr2(do_QueryInterface(serr)); rv = serr2->InitWithWindowID(description.get(), mURISpec.get(), mLastLine.get(), lineNumber, colNumber, nsIScriptError::errorFlag, "malformed-xml", mInnerWindowID); } // If it didn't initialize, we can't do any logging. PRBool shouldReportError = NS_SUCCEEDED(rv); if (mSink && shouldReportError) { rv = mSink->ReportError(errorText.get(), sourceText.get(), serr, &shouldReportError); if (NS_FAILED(rv)) { shouldReportError = PR_TRUE; } } if (shouldReportError) { nsCOMPtr<nsIConsoleService> cs (do_GetService(NS_CONSOLESERVICE_CONTRACTID)); if (cs) { cs->LogMessage(serr); } } return NS_ERROR_HTMLPARSER_STOPPARSING; }
int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) { FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; FAR struct join_s *pjoin; int ret; sinfo("thread=%d group=%p\n", thread, group); DEBUGASSERT(group); /* pthread_join() is a cancellation point */ (void)enter_cancellation_point(); /* First make sure that this is not an attempt to join to * ourself. */ if ((pid_t)thread == getpid()) { leave_cancellation_point(); return EDEADLK; } /* Make sure no other task is mucking with the data structures * while we are performing the following operations. NOTE: * we can be also sure that pthread_exit() will not execute * because it will also attempt to get this semaphore. */ (void)pthread_takesemaphore(&group->tg_joinsem); /* Find the join information associated with this thread. * This can fail for one of three reasons: (1) There is no * thread associated with 'thread,' (2) the thread is a task * and does not have join information, or (3) the thread * was detached and has exited. */ pjoin = pthread_findjoininfo(group, (pid_t)thread); if (!pjoin) { /* Determine what kind of error to return */ FAR struct tcb_s *tcb = sched_gettcb((pthread_t)thread); serr("ERROR: Could not find thread data\n"); /* Case (1) or (3) -- we can't tell which. Assume (3) */ if (!tcb) { ret = ESRCH; } /* The thread is still active but has no join info. In that * case, it must be a task and not a pthread. */ else { ret = EINVAL; } (void)pthread_givesemaphore(&group->tg_joinsem); } else { /* We found the join info structure. Increment for the reference * to the join structure that we have. This will keep things * stable for we have to do */ sched_lock(); pjoin->crefs++; /* Check if the thread is still running. If not, then things are * simpler. There are still race conditions to be concerned with. * For example, there could be multiple threads executing in the * 'else' block below when we enter! */ if (pjoin->terminated) { sinfo("Thread has terminated\n"); /* Get the thread exit value from the terminated thread. */ if (pexit_value) { sinfo("exit_value=0x%p\n", pjoin->exit_value); *pexit_value = pjoin->exit_value; } } else { sinfo("Thread is still running\n"); /* Relinquish the data set semaphore. Since pre-emption is * disabled, we can be certain that no task has the * opportunity to run between the time we relinquish the * join semaphore and the time that we wait on the thread exit * semaphore. */ (void)pthread_givesemaphore(&group->tg_joinsem); /* Take the thread's thread exit semaphore. We will sleep here * until the thread exits. We need to exercise caution because * there could be multiple threads waiting here for the same * pthread to exit. */ (void)pthread_takesemaphore(&pjoin->exit_sem); /* The thread has exited! Get the thread exit value */ if (pexit_value) { *pexit_value = pjoin->exit_value; sinfo("exit_value=0x%p\n", pjoin->exit_value); } /* Post the thread's data semaphore so that the exiting thread * will know that we have received the data. */ (void)pthread_givesemaphore(&pjoin->data_sem); /* Retake the join semaphore, we need to hold this when * pthread_destroyjoin is called. */ (void)pthread_takesemaphore(&group->tg_joinsem); } /* Pre-emption is okay now. The logic still cannot be re-entered * because we hold the join semaphore */ sched_unlock(); /* Release our reference to the join structure and, if the reference * count decrements to zero, deallocate the join structure. */ if (--pjoin->crefs <= 0) { (void)pthread_destroyjoin(group, pjoin); } (void)pthread_givesemaphore(&group->tg_joinsem); ret = OK; } leave_cancellation_point(); sinfo("Returning %d\n", ret); return ret; }
static inline int mod_sectname(FAR struct mod_loadinfo_s *loadinfo, FAR const Elf32_Shdr *shdr) { FAR Elf32_Shdr *shstr; FAR uint8_t *buffer; off_t offset; size_t readlen; size_t bytesread; int shstrndx; int ret; /* Get the section header table index of the entry associated with the * section name string table. If the file has no section name string table, * this member holds the value SH_UNDEF. */ shstrndx = loadinfo->ehdr.e_shstrndx; if (shstrndx == SHN_UNDEF) { serr("ERROR: No section header string table\n"); return -EINVAL; } /* Get the section name string table section header */ shstr = &loadinfo->shdr[shstrndx]; /* Get the file offset to the string that is the name of the section. This * is the sum of: * * shstr->sh_offset: The file offset to the first byte of the section * header string table data. * shdr->sh_name: The offset to the name of the section in the section * name table */ offset = shstr->sh_offset + shdr->sh_name; /* Loop until we get the entire section name into memory */ buffer = loadinfo->iobuffer; bytesread = 0; for (; ; ) { /* Get the number of bytes to read */ readlen = loadinfo->buflen - bytesread; if (offset + readlen > loadinfo->filelen) { if (loadinfo->filelen <= offset) { serr("ERROR: At end of file\n"); return -EINVAL; } readlen = loadinfo->filelen - offset; } /* Read that number of bytes into the array */ buffer = &loadinfo->iobuffer[bytesread]; ret = mod_read(loadinfo, buffer, readlen, offset); if (ret < 0) { serr("ERROR: Failed to read section name: %d\n", ret); return ret; } bytesread += readlen; /* Did we read the NUL terminator? */ if (memchr(buffer, '\0', readlen) != NULL) { /* Yes, the buffer contains a NUL terminator. */ return OK; } /* No.. then we have to read more */ ret = mod_reallocbuffer(loadinfo, CONFIG_MODULE_BUFFERINCR); if (ret < 0) { serr("ERROR: mod_reallocbuffer failed: %d\n", ret); return ret; } } /* We will not get here */ return OK; }
pid_t task_vforkstart(FAR struct task_tcb_s *child) { struct tcb_s *parent = this_task(); pid_t pid; int rc; int ret; sinfo("Starting Child TCB=%p, parent=%p\n", child, this_task()); DEBUGASSERT(child); /* Duplicate the original argument list in the forked child TCB */ ret = vfork_argsetup(parent, child); if (ret < 0) { task_vforkabort(child, -ret); return ERROR; } /* Now we have enough in place that we can join the group */ #ifdef HAVE_TASK_GROUP ret = group_initialize(child); if (ret < 0) { task_vforkabort(child, -ret); return ERROR; } #endif /* Get the assigned pid before we start the task */ pid = (int)child->cmn.pid; /* Eliminate a race condition by disabling pre-emption. The child task * can be instantiated, but cannot run until we call waitpid(). This * assures us that we cannot miss the the death-of-child signal (only * needed in the SMP case). */ sched_lock(); /* Activate the task */ ret = task_activate((FAR struct tcb_s *)child); if (ret < OK) { task_vforkabort(child, -ret); sched_unlock(); return ERROR; } /* The child task has not yet ran because pre-emption is disabled. * The child task has the same priority as the parent task, so that * would typically be the case anyway. However, in the SMP * configuration, the child thread might have already ran on * another CPU if pre-emption were not disabled. * * It is a requirement that the parent environment be stable while * vfork runs; the child thread is still dependent on things in the * parent thread... like the pointers into parent thread's stack * which will still appear in the child's registers and environment. * * We assure that by waiting for the child thread to exit before * returning to the parent thread. NOTE that pre-emption will be * re-enabled while we are waiting, giving the child thread the * opportunity to run. */ rc = 0; #ifdef CONFIG_DEBUG_FEATURES ret = waitpid(pid, &rc, 0); if (ret < 0) { serr("ERROR: waitpid failed: %d\n", errno); } #else (void)waitpid(pid, &rc, 0); #endif sched_unlock(); return pid; }
pid_t up_vfork(const struct vfork_s *context) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; size_t stacksize; uint32_t newsp; #ifdef CONFIG_MIPS32_FRAMEPOINTER uint32_t newfp; #endif uint32_t stackutil; size_t argsize; void *argv; int ret; sinfo("s0:%08x s1:%08x s2:%08x s3:%08x s4:%08x\n", context->s0, context->s1, context->s2, context->s3, context->s4); #ifdef CONFIG_MIPS32_FRAMEPOINTER sinfo("s5:%08x s6:%08x s7:%08x\n", context->s5, context->s6, context->s7); #ifdef MIPS32_SAVE_GP sinfo("fp:%08x sp:%08x ra:%08x gp:%08x\n", context->fp, context->sp, context->ra, context->gp); #else sinfo("fp:%08x sp:%08x ra:%08x\n", context->fp context->sp, context->ra); #endif #else sinfo("s5:%08x s6:%08x s7:%08x s8:%08x\n", context->s5, context->s6, context->s7, context->s8); #ifdef MIPS32_SAVE_GP sinfo("sp:%08x ra:%08x gp:%08x\n", context->sp, context->ra, context->gp); #else sinfo("sp:%08x ra:%08x\n", context->sp, context->ra); #endif #endif /* Allocate and initialize a TCB for the child task. */ child = task_vforksetup((start_t)context->ra, &argsize); if (!child) { sinfo("task_vforksetup failed\n"); return (pid_t)ERROR; } sinfo("Parent=%p Child=%p\n", parent, child); /* Get the size of the parent task's stack. Due to alignment operations, * the adjusted stack size may be smaller than the stack size originally * requrested. */ stacksize = parent->adj_stack_size + CONFIG_STACK_ALIGNMENT - 1; /* Allocate the stack for the TCB */ ret = up_create_stack((FAR struct tcb_s *)child, stacksize + argsize, parent->flags & TCB_FLAG_TTYPE_MASK); if (ret != OK) { serr("ERROR: up_create_stack failed: %d\n", ret); task_vforkabort(child, -ret); return (pid_t)ERROR; } /* Allocate the memory and copy argument from parent task */ argv = up_stack_frame((FAR struct tcb_s *)child, argsize); memcpy(argv, parent->adj_stack_ptr, argsize); /* How much of the parent's stack was utilized? The MIPS uses * a push-down stack so that the current stack pointer should * be lower than the initial, adjusted stack pointer. The * stack usage should be the difference between those two. */ DEBUGASSERT((uint32_t)parent->adj_stack_ptr > context->sp); stackutil = (uint32_t)parent->adj_stack_ptr - context->sp; sinfo("stacksize:%d stackutil:%d\n", stacksize, stackutil); /* Make some feeble effort to perserve the stack contents. This is * feeble because the stack surely contains invalid pointers and other * content that will not work in the child context. However, if the * user follows all of the caveats of vfork() usage, even this feeble * effort is overkill. */ newsp = (uint32_t)child->cmn.adj_stack_ptr - stackutil; memcpy((void *)newsp, (const void *)context->sp, stackutil); /* Was there a frame pointer in place before? */ #ifdef CONFIG_MIPS32_FRAMEPOINTER if (context->fp <= (uint32_t)parent->adj_stack_ptr && context->fp >= (uint32_t)parent->adj_stack_ptr - stacksize) { uint32_t frameutil = (uint32_t)parent->adj_stack_ptr - context->fp; newfp = (uint32_t)child->cmn.adj_stack_ptr - frameutil; } else { newfp = context->fp; } sinfo("Old stack base:%08x SP:%08x FP:%08x\n", parent->adj_stack_ptr, context->sp, context->fp); sinfo("New stack base:%08x SP:%08x FP:%08x\n", child->cmn.adj_stack_ptr, newsp, newfp); #else sinfo("Old stack base:%08x SP:%08x\n", parent->adj_stack_ptr, context->sp); sinfo("New stack base:%08x SP:%08x\n", child->cmn.adj_stack_ptr, newsp); #endif /* Update the stack pointer, frame pointer, global pointer and saved * registers. When the child TCB was initialized, all of the values * were set to zero. up_initial_state() altered a few values, but the * return value in v0 should be cleared to zero, providing the * indication to the newly started child thread. */ child->cmn.xcp.regs[REG_S0] = context->s0; /* Saved register s0 */ child->cmn.xcp.regs[REG_S1] = context->s1; /* Saved register s1 */ child->cmn.xcp.regs[REG_S2] = context->s2; /* Saved register s2 */ child->cmn.xcp.regs[REG_S3] = context->s3; /* Volatile register s3 */ child->cmn.xcp.regs[REG_S4] = context->s4; /* Volatile register s4 */ child->cmn.xcp.regs[REG_S5] = context->s5; /* Volatile register s5 */ child->cmn.xcp.regs[REG_S6] = context->s6; /* Volatile register s6 */ child->cmn.xcp.regs[REG_S7] = context->s7; /* Volatile register s7 */ #ifdef CONFIG_MIPS32_FRAMEPOINTER child->cmn.xcp.regs[REG_FP] = newfp; /* Frame pointer */ #else child->cmn.xcp.regs[REG_S8] = context->s8; /* Volatile register s8 */ #endif child->cmn.xcp.regs[REG_SP] = newsp; /* Stack pointer */ #ifdef MIPS32_SAVE_GP child->cmn.xcp.regs[REG_GP] = newsp; /* Global pointer */ #endif /* And, finally, start the child task. On a failure, task_vforkstart() * will discard the TCB by calling task_vforkabort(). */ return task_vforkstart(child); }
void mother_envsetup(void) { const char *function = "mother_envsetup()"; const int exitsignalv[] = { SIGINT, SIGQUIT, SIGBUS, SIGSEGV, SIGTERM, SIGILL, SIGFPE #ifdef SIGSYS , SIGSYS #endif /* SIGSYS */ }; const size_t pipetomotherfds = 2; /* fds needed for pipe to mother. */ const size_t exitsignalc = ELEMENTS(exitsignalv); const int ignoresignalv[] = { SIGPIPE }; const size_t ignoresignalc = ELEMENTS(ignoresignalv); struct sigaction sigact; struct rlimit rlimit; #ifdef RLIMIT_NPROC struct rlimit maxproc; #endif /* RLIMIT_NPROC */ rlim_t maxopenfd, minfd_neg, minfd_req, minfd_io, minfd; size_t i, fdreserved; for (fdreserved = 0; fdreserved < ELEMENTS(sockscf.state.reservedfdv); ++fdreserved) if ((sockscf.state.reservedfdv[fdreserved] = makedummyfd(0, 0)) == -1) serr("%s: could not reserve fd #%lu for later use", function, (unsigned long)fdreserved + 1); /* * close any descriptor we don't need, both in case of chroot(2) * and for needing every descriptor we can get. */ /* assume syslog uses one */ fdreserved += sockscf.log.type & LOGTYPE_SYSLOG ? 0 : 1; /* * shmem-segments we may need to attach to temporarily in relation * to doing rulespermit() and similar for a client. */ fdreserved += 1 /* bw fd */ + 1 /* session fd */ + 1; /* monitor fd */ for (i = 0, maxopenfd = getmaxofiles(softlimit); (rlim_t)i < maxopenfd; ++i) { size_t j; if (descriptorisreserved((int)i)) { ++fdreserved; continue; } /* sockets we listen on. */ for (j = 0; j < sockscf.internal.addrc; ++j) { if ((int)i == sockscf.internal.addrv[j].s) break; } if (j < sockscf.internal.addrc) /* listening on this socket. */ continue; close((int)i); } errno = 0; newprocinit(); /* just in case the above closed a syslog(3) fd. */ /* * Check system limits against what we need. * Enough descriptors for each child process? + 2 for the pipes from * the child to mother. */ minfd_neg = (SOCKD_NEGOTIATEMAX * 1) + pipetomotherfds + fdreserved; minfd_req = (SOCKD_REQUESTMAX * FDPASS_MAX) + pipetomotherfds + fdreserved; minfd_io = (SOCKD_IOMAX * FDPASS_MAX) + pipetomotherfds + fdreserved; /* i/o process stays attached to bw and monitor shmem all the time. */ minfd_io += SOCKD_IOMAX * (1 + 1); #if BAREFOOTD minfd_io += MIN(10, MIN_UDPCLIENTS); #endif slog(LOG_DEBUG, "%s: minfd_negotiate: %lu, minfd_request: %lu, minfd_io: %lu", function, (unsigned long)minfd_neg, (unsigned long)minfd_req, (unsigned long)minfd_io); /* * need to know max number of open files so we can allocate correctly * sized fd_sets. Also, try to set both it and the max number of * processes to the hard limit. */ sockscf.state.maxopenfiles = getmaxofiles(hardlimit); slog(LOG_DEBUG, "hard limit for max number of open files is %lu, soft limit is %lu", (unsigned long)sockscf.state.maxopenfiles, (unsigned long)getmaxofiles(softlimit)); if (sockscf.state.maxopenfiles == RLIM_INFINITY) { sockscf.state.maxopenfiles = getmaxofiles(softlimit); SASSERTX(sockscf.state.maxopenfiles != RLIM_INFINITY); } minfd = MAX(minfd_neg, MAX(minfd_req, minfd_io)); if (sockscf.state.maxopenfiles < minfd) { slog(LOG_INFO, "have only %lu file descriptors available, but need at least %lu " "according to the configuration. Trying to increase it ...", (unsigned long)sockscf.state.maxopenfiles, (unsigned long)minfd); sockscf.state.maxopenfiles = minfd; } rlimit.rlim_cur = rlimit.rlim_max = sockscf.state.maxopenfiles; if (setrlimit(RLIMIT_OFILE, &rlimit) == 0) slog(LOG_DEBUG, "max number of file descriptors is now %lu", (unsigned long)sockscf.state.maxopenfiles); else { const char *problem; sockscf.state.maxopenfiles = getmaxofiles(hardlimit); if (sockscf.state.maxopenfiles < minfd_neg) problem = "SOCKD_NEGOTIATEMAX"; else if (sockscf.state.maxopenfiles < minfd_req) problem = "SOCKD_REQUESTMAX"; else if (sockscf.state.maxopenfiles < minfd_io) problem = "SOCKD_IOMAX"; else SERRX(sockscf.state.maxopenfiles); serrx("%s: failed to increase the max number of open file descriptors " "for ourselves via setrlimit(RLIMIT_OFILE) to %lu: %s. " "Increase the kernel/shell's max open files limit, or reduce " "the %s value in %s's include/config.h, or we will be unable to " "start up", function, (unsigned long)rlimit.rlim_max, strerror(errno), problem, PRODUCT); } #ifdef RLIMIT_NPROC if (getrlimit(RLIMIT_NPROC, &maxproc) != 0) swarn("getrlimit(RLIMIT_NPROC) failed"); else { maxproc.rlim_cur = maxproc.rlim_max; if (setrlimit(RLIMIT_NPROC, &maxproc) != 0) swarn("setrlimit(RLIMIT_NPROC, { %lu, %lu }) failed", (unsigned long)rlimit.rlim_cur, (unsigned long)rlimit.rlim_max); } #endif /* !RLIMIT_NPROC */ /* * set up signal handlers. */ bzero(&sigact, sizeof(sigact)); sigact.sa_flags = SA_RESTART | SA_NOCLDSTOP | SA_SIGINFO; sigact.sa_sigaction = siginfo; #if HAVE_SIGNAL_SIGINFO if (sigaction(SIGINFO, &sigact, NULL) != 0) serr("sigaction(SIGINFO)"); #endif /* HAVE_SIGNAL_SIGINFO */ /* * same handler, for systems without SIGINFO, as well as systems with * broken ("more secure") signal semantics. */ if (sigaction(SIGUSR1, &sigact, NULL) != 0) serr("sigaction(SIGUSR1)"); sigact.sa_sigaction = sighup; if (sigaction(SIGHUP, &sigact, NULL) != 0) serr("sigaction(SIGHUP)"); sigact.sa_sigaction = sigchld; if (sigaction(SIGCHLD, &sigact, NULL) != 0) serr("sigaction(SIGCHLD)"); sigact.sa_sigaction = sigterm; for (i = 0; (size_t)i < exitsignalc; ++i) if (sigaction(exitsignalv[i], &sigact, NULL) != 0) serr("sigaction(%d)", exitsignalv[i]); sigact.sa_handler = SIG_IGN; for (i = 0; (size_t)i < ignoresignalc; ++i) if (sigaction(ignoresignalv[i], &sigact, NULL) != 0) serr("sigaction(%d)", ignoresignalv[i]); sigact.sa_flags = SA_SIGINFO; /* want to be interrupted. */ sigact.sa_sigaction = sigalrm; if (sigaction(SIGALRM, &sigact, NULL) != 0) serr("sigaction(SIGALRM)"); if (sockscf.option.daemon) { if (daemon(1, 0) != 0) serr("daemon()"); newprocinit(); /* for daemon(). */ close(STDIN_FILENO); /* leave stdout/stderr, but close stdin. */ *sockscf.state.motherpidv = getpid(); /* we are the main mother. */ } if (HAVE_ENABLED_PIDFILE) { FILE *fp; sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_ON); if ((fp = fopen(sockscf.option.pidfile, "w")) == NULL) { swarn("open(%s)", sockscf.option.pidfile); errno = 0; } sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_OFF); if (fp != NULL) { if (fprintf(fp, "%lu\n", (unsigned long)sockscf.state.pid) == EOF) swarn("failed writing pid to pidfile %s", sockscf.option.pidfile); else sockscf.option.pidfilewritten = 1; fclose(fp); } } enable_childcreate(); freedescriptors(NULL, &sockscf.state.highestfdinuse); }
/////////////////////////////////////////////////////////////////////////// ////sctypSizeOf//////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// int sctypSizeOf(scType * type) { // deb("sctypSizeOf(where=%s)",TYPESTR); scAssert(sctypSizeOf, type); // scIntAssert(sctypSizeOf,sym->add); if (TYPESTR && TYPESTR[0]) { if (TYPESTR[0] == '&') //reference return 4; /* {char *cq=TYPESTR; int i; TYPESTR++; i=sctypSizeOf(type); TYPESTR=cq; return i; }*/ if (TYPESTR[0] == '(') return 4; //function if (TYPESTR[0] == '*' || (TYPESTR[0] == '[' && TYPESTR[1] == ']')) return 4; //pointer if (TYPESTR[0] == '[') //TABLE { int i = 0, c = 1; char *cq; while (TYPESTR[c] != ']') { i = i * 10 + (TYPESTR[c] - '0'); c++; } cq = TYPESTR; TYPESTR += c + 1; i *= sctypSizeOf(type); TYPESTR = cq; return i; } } { //no params //type is a struct switch (type->flags & typTYPE) { case typSCRIPT: { int size = 12; //structs scSymbol *sc = type->main; do { if (!(sc->adr.flags & adrTYPEONLY)) size += 4; sc = sc->next; } while (sc); return size; } case typSTRUCT: { int size = 0, j, k, l; //structs scSymbol *sc = type->main; l = sctypInsistsAlignment(&sc->type); while (sc) { if (!sctypIsFunction(&sc->type) && !(sc->adr.flags & adrTYPEONLY)) { j = sctypSizeOf(&sc->type); k = sctypInsistsAlignment(&sc->type); if (k && size % k) size += k - size % k; } else j = 0; size += j; //unpack shorts and bytes sc = sc->next; }; if (l && size % l) size += l - size % l; //DJGPP sizeof compatibility return size; } case typPREDEFINED: { // deb("sizeof(PRE:%d)\n",sym->add->main); return Standard_Types[(int) type->main].size; } case typUSERDEFINED: { // deb("sizeof(user:%s)\n",sym->name); return (sctypSizeOf(&type->main->type)); } } } serr(scErr_Internal, "internal compiler error"); }
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLn, int nShowCmd) { bool good_engine; std::string cmd_str(lpCmdLn); std::vector<std::string> args; /* get 'our' module name */ SmartBuffer<CHAR> module_buf(MAX_PATH); GetModuleFileName(NULL, module_buf.get(), MAX_PATH); /* start logging */ std::string logpath(TOSDB_LOG_PATH); logpath.append(LOG_NAME); StartLogging(logpath.c_str()); /* add the appropriate engine name to the module path */ std::string path(module_buf.get()); std::string serv_ext(path.begin() + path.find_last_of("-"), path.end()); #ifdef _DEBUG if(serv_ext != "-x86_d.exe" && serv_ext != "-x64_d.exe"){ #else if(serv_ext != "-x86.exe" && serv_ext != "-x64.exe"){ #endif TOSDB_LogH("STARTUP", "service path doesn't provide proper extension"); return 1; } path.erase(path.find_last_of("\\")); engine_path = path; engine_path.append("\\").append(ENGINE_BASE_NAME).append(serv_ext); GetSystemInfo(&sys_info); ParseArgs(args,cmd_str); size_t argc = args.size(); int admin_pos = 0; int no_service_pos = 0; /* look for --admin and/or --noservice args */ if(argc > 0 && args[0] == "--admin") admin_pos = 1; else if(argc > 1 && args[1] == "--admin") admin_pos = 2; if(argc > 0 && args[0] == "--noservice") no_service_pos = 1; else if(argc > 1 && args[1] == "--noservice") no_service_pos = 2; switch(argc){ /* look for custom_session arg */ case 0: break; case 1: if(admin_pos == 0 && no_service_pos == 0) custom_session = std::stoi(args[0]); break; case 2: if( (admin_pos == 1 && no_service_pos != 2) || (no_service_pos == 1 && admin_pos != 2)) { custom_session = std::stoi(args[1]); } break; case 3: if(admin_pos > 0 && no_service_pos > 0) custom_session = std::stoi(args[2]); break; default: std::string serr("invalid # of args: "); serr.append(std::to_string(argc)); TOSDB_LogH("STARTUP",serr.c_str()); return 1; } std::stringstream ss_args; ss_args << "argc: " << std::to_string(argc) << " custom_session: " << std::to_string(custom_session) << " admin_pos: " << std::to_string(admin_pos) << " no_service_pos: " << std::to_string(no_service_pos); TOSDB_Log("STARTUP", std::string("lpCmdLn: ").append(cmd_str).c_str() ); TOSDB_Log("STARTUP", ss_args.str().c_str() ); integrity_level = admin_pos > 0 ? "High Mandatory Level" : "Medium Mandatory Level"; /* populate the engine command and if --noservice is passed jump right into the engine via SpawnRestrictedProcess; otherwise Start the service which will handle that for us prepend '--spawned' so engine knows *we* called it; if someone else passes '--spawned' they deserve what they get */ if(no_service_pos > 0){ is_service = false; TOSDB_Log("STARTUP", "starting tos-databridge-engine.exe directly(NOT A SERVICE)"); good_engine = SpawnRestrictedProcess("--spawned --noservice", custom_session); if(!good_engine){ std::string serr("failed to spawn "); serr.append(engine_path).append(" --spawned --noservice"); TOSDB_LogH("STARTUP", serr.c_str()); } }else{ SERVICE_TABLE_ENTRY dTable[] = { {SERVICE_NAME,ServiceMain}, {NULL,NULL} }; /* START SERVICE */ if( !StartServiceCtrlDispatcher(dTable) ){ TOSDB_LogH("STARTUP", "StartServiceCtrlDispatcher() failed. " "(Be sure to use an appropriate Window's tool to start the service " "(e.g SC.exe, Services.msc) or pass '--noservice' to run directly.)"); } } StopLogging(); return 0; }
void WINAPI ServiceMain(DWORD argc, LPSTR argv[]) { bool good_engine; service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwCurrentState = SERVICE_START_PENDING; service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN; service_status.dwWin32ExitCode = NO_ERROR; service_status.dwServiceSpecificExitCode = 0; service_status.dwCheckPoint = 0; service_status.dwWaitHint = (DWORD)(2.5 * UPDATE_PERIOD); service_status_hndl = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceController); if(!service_status_hndl){ TOSDB_LogH("ADMIN","failed to register control handler, exiting"); service_status.dwCurrentState = SERVICE_STOPPED; service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; service_status.dwServiceSpecificExitCode = 1; UpdateStatus(SERVICE_STOPPED, -1); return; } TOSDB_Log("ADMIN","successfully registered control handler"); SetServiceStatus(service_status_hndl, &service_status); TOSDB_Log("STATE","SERVICE_START_PENDING"); TOSDB_Log("ADMIN","starting service update loop on its own thread"); /* spin off the basic service update loop */ std::async( std::launch::async, [&] { while(!shutdown_flag){ Sleep(UPDATE_PERIOD); UpdateStatus(-1, -1); } } ); TOSDB_Log("STARTUP", "try to start tos-databridge-engine.exe (AS A SERVICE)"); /* create new process that can communicate with our interface */ good_engine = SpawnRestrictedProcess("--spawned --service", custom_session); if(!good_engine){ std::string serr("failed to spawn "); serr.append(engine_path).append(" --spawned --service"); TOSDB_LogH("STARTUP", serr.c_str()); }else{ /* on success, update and block */ UpdateStatus(SERVICE_RUNNING, -1); TOSDB_Log("STATE","SERVICE_RUNNING"); WaitForSingleObject(engine_pinfo.hProcess, INFINITE); } /*** IF WE GET HERE WE WILL SHUTDOWN ***/ UpdateStatus(SERVICE_STOPPED, 0); TOSDB_Log("STATE","SERVICE_STOPPED"); }
/////////////////////////////////////////////////////////////////////////// ////scsReadDirectInitialization/////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// //returns 0, if all was read and nothing (but push init_end) remains to be //done, else returns number of bytes to be copied static int scsReadDirectInitialization(scSymbol * deli, scType * type, bool packed, pmem * dest, int type_size, scSymbol * sym) { _value val; /* write to inits or consts*/ #if DEBUGLEVEL==0 deb2(": %s%s", sciValTypeStr(sctypGetValType(type)), packed ? " as packed" : ""); deb1(" (%db)", type_size); if (deli) //inside a function - initialize on the stack { deb0(" on the stack\n"); } else { deb0(" on the heap\n"); } #endif if (type->params && type->params[0]) { /*******************************************Pointer - OK*/ if (type->params[0] == '*' /*||(type->params[0]=='['&&type->params[1]==']') */ ) { //x* t; scType inner_type = *type; inner_type.params++; sctypSimplifyType(&inner_type); #if DEBUGLEVEL==0 deb0("* Pointer"); //Advance; deb1(" %s ", ST->lexema); #endif scAssert(scsReadDirectInitialization, type_size == 4); scget_back(ST); /*as STRING*/ if (ST->lexema[0] == '"') { if (sctypGetValType(&inner_type) != valCHAR) serr(scErr_Declaration, "Illegal array initialization with string"); if (deli) { _value val1, val2; char *s = ST->lexema + 1; s[strlen(s) - 1] = 0; // j=4; #if DEBUGLEVEL==0 deb1("Storing %s\n", s); #endif if (sym) { init_start = act.consts.pos; //inits will be earlier by 4 bytes. s = scStrdup(s); scvalConstantString(&val2, s); // pushstr_pmem(&act.consts,s); Gen_Opcode(opvcpuPUSH, &val2, NULL); } else { pushstr_pmem(&init_end, s); push_pmem(&act.consts, 4, s); //copy to consts anything as pointer Gen_Opcode(opvcpuMOV, scvalSetRegister(&val1, valINT, 0), scvalSetRegister(&val2, valINT, regES)); Gen_Opcode(opvcpuADD, scvalSetRegister(&val1, valINT, 0), scvalSetINT(&val2, init_start)); scvalSetINT(&val1, init_pos); val1.adr.flags = adrBP; val1.adr.address = init_pos; Gen_Opcode(opvcpuMOV, &val1, scvalSetRegister(&val2, valINT, 0)); } init_start += strlen(s) + 1; if (sym) { Advance; Advance; return 0; } //all done } else { int x = -2, y = init_start + act.inits.pos; char *s = ST->lexema + 1; // j=4; s[strlen(s) - 1] = 0; #if DEBUGLEVEL==0 deb1("Storing %s\n", s); deb3("(%d,%d,%d)", y, x, act.consts.pos); #endif push_pmem(&act.inits, 4, &y); //can be anything push_pmem(&init_end, 4, &y); //destination position push_pmem(&init_end, 4, &x); //size=-2:ES //copy to consts segment push_pmem(&init_end, 4, &act.consts.pos); #if DEBUGLEVEL==0 deb1("after %d,", init_end.pos); #endif pushstr_pmem(&act.consts, s); } Advance; Advance; return 4; } else if (lexeq("{")) { serr(scErr_Declaration, "Don't use {} in initialization of pointer."); } else /*as VARIABLE*/ { //exit to primitive read } } //Pointer* else /*******************************************Table*/ if (type->params[0] == '[') { //x t[xx]; scType tp = *type; int tabsize, initsize = 0, inner_type_size; #if DEBUGLEVEL==0 deb0("Table"); #endif tp.params++; tabsize = strtoul(tp.params, &tp.params, 10); scAssert(Read_Init_Type[], *tp.params == ']'); tp.params++; sctypSimplifyType(&tp); inner_type_size = sctypSizeOf(&tp); #if DEBUGLEVEL==0 deb2("[%d] of %d bytes;\n", tabsize, inner_type_size); #endif //Advance; if (ST->lexema[0] == '"') { char *data; /*as STRING*/ if (sctypGetValType(&tp) != valCHAR) serr(scErr_Declaration, "Illegal array initialization with string"); #if DEBUGLEVEL==0 deb1("char[%d] init\n", tabsize); #endif data = scStrdup(ST->lexema + 1); data[strlen(data) - 1] = 0; //erase " pushstr_pmem(dest, data); /* {char temp[100]; int i=tabsize-strlen(data)-1; while(i) if (i>100) {push_pmem(dest,100,temp);i-=100;} else {push_pmem(dest,i,temp);i=0;} }*/ initsize = strlen(data) + 1; /*initialize all the data, if packed */ if (packed && initsize < type_size) { char c = 0; int i; for (i = initsize; i < type_size; i++) push_pmem(dest, 1, &c); initsize = type_size; } scFree(data); Advance; return initsize; } else if (lexeq("{")) { int i = 0, j; for (; i < tabsize; i++) { Advance; j = scsReadDirectInitialization(deli, &tp, true, dest, inner_type_size, NULL); init_pos += inner_type_size; scAssert(scsReadDirectInitialization[], j); //same here initsize += j; if (i < tabsize - 1) { if (!lexeq(",")) serr2(scErr_Parse, parse_error, ST->lexema); } } if (lexeq(",")) { Advance; } if (!lexeq("}")) serr2(scErr_Parse, parse_error, ST->lexema); Advance; return initsize; } else //VARIABLE { serr2(scErr_Parse, parse_error, ST->lexema); } } //Table[] }
int board_app_initialize(uintptr_t arg) { #ifdef HAVE_RTC_DRIVER FAR struct rtc_lowerhalf_s *rtclower; #endif int ret; (void)ret; /* Configure CPU load estimation */ #ifdef CONFIG_SCHED_INSTRUMENTATION cpuload_initialize_once(); #endif #ifdef HAVE_PROC /* Mount the proc filesystem */ syslog(LOG_INFO, "Mounting procfs to /proc\n"); ret = mount(NULL, CONFIG_NSH_PROC_MOUNTPOINT, "procfs", 0, NULL); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to mount the PROC filesystem: %d (%d)\n", ret, errno); return ret; } #endif #ifdef HAVE_RTC_DRIVER /* Instantiate the STM32L4 lower-half RTC driver */ rtclower = stm32l4_rtc_lowerhalf(); if (!rtclower) { serr("ERROR: Failed to instantiate the RTC lower-half driver\n"); return -ENOMEM; } else { /* Bind the lower half driver and register the combined RTC driver * as /dev/rtc0 */ ret = rtc_initialize(0, rtclower); if (ret < 0) { serr("ERROR: Failed to bind/register the RTC driver: %d\n", ret); return ret; } } #endif #ifdef HAVE_MMCSD /* First, get an instance of the SDIO interface */ g_sdio = sdio_initialize(CONFIG_NSH_MMCSDSLOTNO); if (!g_sdio) { syslog(LOG_ERR, "ERROR: Failed to initialize SDIO slot %d\n", CONFIG_NSH_MMCSDSLOTNO); return -ENODEV; } /* Now bind the SDIO interface to the MMC/SD driver */ ret = mmcsd_slotinitialize(CONFIG_NSH_MMCSDMINOR, g_sdio); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); return ret; } /* Then let's guess and say that there is a card in the slot. There is no * card detect GPIO. */ sdio_mediachange(g_sdio, true); syslog(LOG_INFO, "[boot] Initialized SDIO\n"); #endif #ifdef CONFIG_AJOYSTICK /* Initialize and register the joystick driver */ ret = board_ajoy_initialize(); if (ret != OK) { syslog(LOG_ERR, "ERROR: Failed to register the joystick driver: %d\n", ret); return ret; } #endif return OK; }
FAR struct task_tcb_s *task_vforksetup(start_t retaddr) { struct tcb_s *parent = this_task(); struct task_tcb_s *child; uint8_t ttype; int priority; int ret; DEBUGASSERT(retaddr); /* Get the type of the fork'ed task (kernel or user) */ if ((parent->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL) { /* Fork'ed from a kernel thread */ ttype = TCB_FLAG_TTYPE_KERNEL; } else { /* Fork'ed from a user task or pthread */ ttype = TCB_FLAG_TTYPE_TASK; } /* Allocate a TCB for the child task. */ child = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s)); if (!child) { serr("ERROR: Failed to allocate TCB\n"); set_errno(ENOMEM); return NULL; } /* Allocate a new task group with the same privileges as the parent */ #ifdef HAVE_TASK_GROUP ret = group_allocate(child, parent->flags); if (ret < 0) { goto errout_with_tcb; } #endif /* Associate file descriptors with the new task */ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 ret = group_setuptaskfiles(child); if (ret < OK) { goto errout_with_tcb; } #endif /* Get the priority of the parent task */ #ifdef CONFIG_PRIORITY_INHERITANCE priority = parent->base_priority; /* "Normal," unboosted priority */ #else priority = parent->sched_priority; /* Current priority */ #endif /* Initialize the task control block. This calls up_initial_state() */ sinfo("Child priority=%d start=%p\n", priority, retaddr); ret = task_schedsetup(child, priority, retaddr, parent->entry.main, ttype); if (ret < OK) { goto errout_with_tcb; } sinfo("parent=%p, returning child=%p\n", parent, child); return child; errout_with_tcb: sched_releasetcb((FAR struct tcb_s *)child, ttype); set_errno(-ret); return NULL; }
int group_setupidlefiles(FAR struct task_tcb_s *tcb) { #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 FAR struct task_group_s *group = tcb->cmn.group; #endif #if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE) int fd; #endif #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 DEBUGASSERT(group); #endif #if CONFIG_NFILE_DESCRIPTORS > 0 /* Initialize file descriptors for the TCB */ files_initlist(&group->tg_filelist); #endif #if CONFIG_NSOCKET_DESCRIPTORS > 0 /* Allocate socket descriptors for the TCB */ net_initlist(&group->tg_socketlist); #endif /* Open stdin, dup to get stdout and stderr. This should always * be the first file opened and, hence, should always get file * descriptor 0. */ #if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE) fd = open("/dev/console", O_RDWR); if (fd == 0) { /* Successfully opened /dev/console as stdin (fd == 0) */ (void)fs_dupfd2(0, 1); (void)fs_dupfd2(0, 2); } else { /* We failed to open /dev/console OR for some reason, we opened * it and got some file descriptor other than 0. */ if (fd > 0) { sinfo("Open /dev/console fd: %d\n", fd); (void)close(fd); } else { serr("ERROR: Failed to open /dev/console: %d\n", errno); } return -ENFILE; } #endif /* Allocate file/socket streams for the TCB */ #if CONFIG_NFILE_STREAMS > 0 return group_setupstreams(tcb); #else return OK; #endif }
int insmod(FAR const char *filename, FAR const char *modulename) { struct mod_loadinfo_s loadinfo; FAR struct module_s *modp; mod_initializer_t initializer; int ret; DEBUGASSERT(filename != NULL && modulename != NULL); sinfo("Loading file: %s\n", filename); /* Get exclusive access to the module registry */ mod_registry_lock(); /* Check if this module is already installed */ if (mod_registry_find(modulename) != NULL) { mod_registry_unlock(); ret = -EEXIST; goto errout_with_lock; } /* Initialize the ELF library to load the program binary. */ ret = mod_initialize(filename, &loadinfo); mod_dumploadinfo(&loadinfo); if (ret != 0) { serr("ERROR: Failed to initialize to load module: %d\n", ret); goto errout_with_lock; } /* Allocate a module registry entry to hold the module data */ modp = (FAR struct module_s *)kmm_zalloc(sizeof(struct module_s)); if (ret != 0) { sinfo("Failed to initialize for load of ELF program: %d\n", ret); goto errout_with_loadinfo; } /* Save the module name in the registry entry */ strncpy(modp->modulename, modulename, MODULENAME_MAX); /* Load the program binary */ ret = mod_load(&loadinfo); mod_dumploadinfo(&loadinfo); if (ret != 0) { sinfo("Failed to load ELF program binary: %d\n", ret); goto errout_with_registry_entry; } /* Bind the program to the kernel symbol table */ ret = mod_bind(&loadinfo); if (ret != 0) { sinfo("Failed to bind symbols program binary: %d\n", ret); goto errout_with_load; } /* Return the load information */ modp->alloc = (FAR void *)loadinfo.textalloc; #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) modp->textsize = loadinfo.textsize; modp->datasize = loadinfo.datasize; #endif /* Get the module initializer entry point */ initializer = (mod_initializer_t)(loadinfo.textalloc + loadinfo.ehdr.e_entry); #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) modp->initializer = initializer; #endif mod_dumpinitializer(initializer, &loadinfo); /* Call the module initializer */ ret = initializer(&modp->uninitializer, &modp->arg); if (ret < 0) { sinfo("Failed to initialize the module: %d\n", ret); goto errout_with_load; } /* Add the new module entry to the registry */ mod_registry_add(modp); mod_uninitialize(&loadinfo); mod_registry_unlock(); return OK; errout_with_load: mod_unload(&loadinfo); errout_with_registry_entry: kmm_free(modp); errout_with_loadinfo: mod_uninitialize(&loadinfo); errout_with_lock: mod_registry_unlock(); set_errno(-ret); return ERROR; }
int board_app_initialize(uintptr_t arg) { #ifdef HAVE_RTC_DRIVER FAR struct rtc_lowerhalf_s *rtclower; #endif #if defined(HAVE_N25QXXX) FAR struct mtd_dev_s *mtd_temp; #endif #if defined(HAVE_N25QXXX_CHARDEV) char blockdev[18]; char chardev[12]; #endif int ret; (void)ret; #ifdef HAVE_PROC /* mount the proc filesystem */ syslog(LOG_INFO, "Mounting procfs to /proc\n"); ret = mount(NULL, CONFIG_NSH_PROC_MOUNTPOINT, "procfs", 0, NULL); if (ret < 0) { syslog(LOG_ERR, "ERROR: Failed to mount the PROC filesystem: %d (%d)\n", ret, errno); return ret; } #endif #ifdef HAVE_RTC_DRIVER /* Instantiate the STM32 lower-half RTC driver */ rtclower = stm32l4_rtc_lowerhalf(); if (!rtclower) { serr("ERROR: Failed to instantiate the RTC lower-half driver\n"); return -ENOMEM; } else { /* Bind the lower half driver and register the combined RTC driver * as /dev/rtc0 */ ret = rtc_initialize(0, rtclower); if (ret < 0) { serr("ERROR: Failed to bind/register the RTC driver: %d\n", ret); return ret; } } #endif #ifdef HAVE_N25QXXX /* Create an instance of the STM32L4 QSPI device driver */ g_qspi = stm32l4_qspi_initialize(0); if (!g_qspi) { _err("ERROR: stm32l4_qspi_initialize failed\n"); return ret; } else { /* Use the QSPI device instance to initialize the * N25QXXX device. */ mtd_temp = n25qxxx_initialize(g_qspi, true); if (!mtd_temp) { _err("ERROR: n25qxxx_initialize failed\n"); return ret; } g_mtd_fs = mtd_temp; #ifdef CONFIG_MTD_PARTITION { FAR struct mtd_geometry_s geo; off_t nblocks; /* Setup a partition of 256KiB for our file system. */ ret = MTD_IOCTL(g_mtd_fs, MTDIOC_GEOMETRY, (unsigned long)(uintptr_t)&geo); if (ret < 0) { _err("ERROR: MTDIOC_GEOMETRY failed\n"); return ret; } nblocks = (256*1024) / geo.blocksize; mtd_temp = mtd_partition(g_mtd_fs, 0, nblocks); if (!mtd_temp) { _err("ERROR: mtd_partition failed\n"); return ret; } g_mtd_fs = mtd_temp; } #endif #ifdef HAVE_N25QXXX_SMARTFS /* Configure the device with no partition support */ ret = smart_initialize(N25QXXX_SMART_MINOR, g_mtd_fs, NULL); if (ret != OK) { _err("ERROR: Failed to initialize SmartFS: %d\n", ret); } #elif defined(HAVE_N25QXXX_NXFFS) /* Initialize to provide NXFFS on the N25QXXX MTD interface */ ret = nxffs_initialize(g_mtd_fs); if (ret < 0) { _err("ERROR: NXFFS initialization failed: %d\n", ret); } /* Mount the file system at /mnt/nxffs */ ret = mount(NULL, "/mnt/nxffs", "nxffs", 0, NULL); if (ret < 0) { _err("ERROR: Failed to mount the NXFFS volume: %d\n", errno); return ret; } #else /* if defined(HAVE_N25QXXX_CHARDEV) */ /* Use the FTL layer to wrap the MTD driver as a block driver */ ret = ftl_initialize(N25QXXX_MTD_MINOR, g_mtd_fs); if (ret < 0) { _err("ERROR: Failed to initialize the FTL layer: %d\n", ret); return ret; } /* Use the minor number to create device paths */ snprintf(blockdev, 18, "/dev/mtdblock%d", N25QXXX_MTD_MINOR); snprintf(chardev, 12, "/dev/mtd%d", N25QXXX_MTD_MINOR); /* Now create a character device on the block device */ /* NOTE: for this to work, you will need to make sure that * CONFIG_FS_WRITABLE is set in the config. It's not a user- * visible setting, but you can make it set by selecting an * arbitrary writable file system (you don't have to actually * use it, just select it so that the block device created via * ftl_initialize() will be writable). */ ret = bchdev_register(blockdev, chardev, false); if (ret < 0) { _err("ERROR: bchdev_register %s failed: %d\n", chardev, ret); return ret; } #endif } #endif #ifdef HAVE_USBHOST /* Initialize USB host operation. stm32l4_usbhost_initialize() starts a thread * will monitor for USB connection and disconnection events. */ ret = stm32l4_usbhost_initialize(); if (ret != OK) { udbg("ERROR: Failed to initialize USB host: %d\n", ret); return ret; } #endif #ifdef HAVE_USBMONITOR /* Start the USB Monitor */ ret = usbmonitor_start(0, NULL); if (ret != OK) { udbg("ERROR: Failed to start USB monitor: %d\n", ret); return ret; } #endif return OK; }
int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) { /* Is there already a stack allocated of a different size? Because of * alignment issues, stack_size might erroneously appear to be of a * different size. Fortunately, this is not a critical operation. */ if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) { /* Yes.. Release the old stack */ up_release_stack(tcb, ttype); } /* Do we need to allocate a new stack? */ if (!tcb->stack_alloc_ptr) { /* Allocate the stack. If DEBUG is enabled (but not stack debug), * then create a zeroed stack to make stack dumps easier to trace. */ #if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) /* Use the kernel allocator if this is a kernel thread */ if (ttype == TCB_FLAG_TTYPE_KERNEL) { tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); } else #endif { /* Use the user-space allocator if this is a task or pthread */ tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); } #ifdef CONFIG_DEBUG_FEATURES /* Was the allocation successful? */ if (!tcb->stack_alloc_ptr) { serr("ERROR: Failed to allocate stack, size %d\n", stack_size); } #endif } /* Did we successfully allocate a stack? */ if (tcb->stack_alloc_ptr) { size_t top_of_stack; size_t size_of_stack; /* Yes.. If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high * water marks. */ #ifdef CONFIG_STACK_COLORATION memset(tcb->stack_alloc_ptr, 0xaa, stack_size); #endif /* The SH family uses a push-down stack: the stack grows * toward loweraddresses in memory. The stack pointer * register, points to the lowest, valid work address * (the "top" of the stack). Items on the stack are * referenced as positive word offsets from sp. */ top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; /* The SH stack must be aligned at word (4 byte) * boundaries. If necessary top_of_stack must be rounded * down to the next boundary */ top_of_stack &= ~3; size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; /* Save the adjusted stack values in the struct tcb_s */ tcb->adj_stack_ptr = (uint32_t*)top_of_stack; tcb->adj_stack_size = size_of_stack; board_autoled_on(LED_STACKCREATED); return OK; } return ERROR; }
APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os, const apr_getopt_option_t *opts, int *optch, const char **optarg) { const char *p; int i; /* Let the calling program reset option processing. */ if (os->reset) { os->place = EMSG; os->ind = 1; os->reset = 0; } /* * We can be in one of two states: in the middle of processing a * run of short options, or about to process a new argument. * Since the second case can lead to the first one, handle that * one first. */ p = os->place; if (*p == '\0') { /* If we are interleaving, skip non-option arguments. */ if (os->interleave) { while (os->ind < os->argc && *os->argv[os->ind] != '-') os->ind++; os->skip_end = os->ind; } if (os->ind >= os->argc || *os->argv[os->ind] != '-') { os->ind = os->skip_start; return APR_EOF; } p = os->argv[os->ind++] + 1; if (*p == '-' && p[1] != '\0') { /* Long option */ /* Search for the long option name in the caller's table. */ apr_size_t len = 0; p++; for (i = 0; ; i++) { if (opts[i].optch == 0) /* No match */ return serr(os, "invalid option", p - 2, APR_BADCH); if (opts[i].name) { len = strlen(opts[i].name); if (strncmp(p, opts[i].name, len) == 0 && (p[len] == '\0' || p[len] == '=')) break; } } *optch = opts[i].optch; if (opts[i].has_arg) { if (p[len] == '=') /* Argument inline */ *optarg = p + len + 1; else { if (os->ind >= os->argc) /* Argument missing */ return serr(os, "missing argument", p - 2, APR_BADARG); else /* Argument in next arg */ *optarg = os->argv[os->ind++]; } } else { *optarg = NULL; if (p[len] == '=') return serr(os, "erroneous argument", p - 2, APR_BADARG); } permute(os); return APR_SUCCESS; } else { if (*p == '-') { /* Bare "--"; we're done */ permute(os); os->ind = os->skip_start; return APR_EOF; } else if (*p == '\0') /* Bare "-" is illegal */ return serr(os, "invalid option", p, APR_BADCH); } } /* * Now we're in a run of short options, and *p is the next one. * Look for it in the caller's table. */ for (i = 0; ; i++) { if (opts[i].optch == 0) /* No match */ return cerr(os, "invalid option character", *p, APR_BADCH); if (*p == opts[i].optch) break; } *optch = *p++; if (opts[i].has_arg) { if (*p != '\0') /* Argument inline */ *optarg = p; else { if (os->ind >= os->argc) /* Argument missing */ return cerr(os, "missing argument", *optch, APR_BADARG); else /* Argument in next arg */ *optarg = os->argv[os->ind++]; } os->place = EMSG; } else { *optarg = NULL; os->place = p; } permute(os); return APR_SUCCESS; }