Example #1
0
/*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);
}
Example #2
0
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;
}
Example #3
0
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, &param);
  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;
}
Example #4
0
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, &param);
      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;
}
Example #6
0
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;
}
Example #7
0
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;
}
Example #8
0
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;
}
Example #9
0
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);
}
Example #10
0
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);
}
Example #11
0
///////////////////////////////////////////////////////////////////////////
////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");
}
Example #12
0
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;
}
Example #13
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");    
}
Example #14
0
///////////////////////////////////////////////////////////////////////////
////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[]
	}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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
}
Example #18
0
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;
}
Example #19
0
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;
}
Example #20
0
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;
}
Example #21
0
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;
}