Exemplo n.º 1
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();
      sdbg("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;
}
Exemplo n.º 2
0
 /* this is just int because we must handle any positive value */
 int status () { return get_errno(); }
Exemplo n.º 3
0
int losetup(FAR const char *devname, FAR const char *filename,
            uint16_t sectsize, off_t offset, bool readonly)
{
  FAR struct loop_struct_s *dev;
  struct stat sb;
  int ret;

  /* Sanity check */

#ifdef CONFIG_DEBUG
  if (!devname || !filename || !sectsize)
    {
      return -EINVAL;
    }
#endif

  /* Get the size of the file */

  ret = stat(filename, &sb);
  if (ret < 0)
    {
      dbg("Failed to stat %s: %d\n", filename, get_errno());
      return -get_errno();
    }

  /* Check if the file system is big enough for one block */

  if (sb.st_size - offset < sectsize)
    {
      dbg("File is too small for blocksize\n");
      return -ERANGE;
    }

  /* Allocate a loop device structure */

  dev = (FAR struct loop_struct_s *)kmm_zalloc(sizeof(struct loop_struct_s));
  if (!dev)
    {
      return -ENOMEM;
    }

  /* Initialize the loop device structure. */

  sem_init(&dev->sem, 0, 1);
  dev->nsectors  = (sb.st_size - offset) / sectsize;
  dev->sectsize  = sectsize;
  dev->offset    = offset;

  /* Open the file. */

#ifdef CONFIG_FS_WRITABLE
  dev->writeenabled = false; /* Assume failure */
  dev->fd           = -1;

  /* First try to open the device R/W access (unless we are asked
   * to open it readonly).
   */

  if (!readonly)
    {
      dev->fd = open(filename, O_RDWR);
    }

  if (dev->fd >= 0)
    {
      dev->writeenabled = true; /* Success */
    }
  else
#endif
    {
      /* If that fails, then try to open the device read-only */

      dev->fd = open(filename, O_RDWR);
      if (dev->fd < 0)
        {
          dbg("Failed to open %s: %d\n", filename, get_errno());
          ret = -get_errno();
          goto errout_with_dev;
        }
    }

  /* Inode private data will be reference to the loop device structure */

  ret = register_blockdriver(devname, &g_bops, 0, dev);
  if (ret < 0)
    {
      fdbg("register_blockdriver failed: %d\n", -ret);
      goto errout_with_fd;
    }

  return OK;

errout_with_fd:
  close(dev->fd);
errout_with_dev:
  kmm_free(dev);
  return ret;
}
Exemplo n.º 4
0
static ssize_t
_gnutls_stream_read (gnutls_session_t session, mbuffer_st **bufel,
		     size_t size, gnutls_pull_func pull_func)
{
  size_t left;
  ssize_t i = 0;
  size_t max_size = _gnutls_get_max_decrypted_data(session);
  char *ptr;
  gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

  *bufel = _mbuffer_alloc (0, MAX(max_size, size));
  if (!*bufel)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }
  ptr = (*bufel)->msg.data;

  session->internals.direction = 0;

  left = size;
  while (left > 0)
    {
      reset_errno (session);

      i = pull_func (fd, &ptr[size - left], left);

      if (i < 0)
        {
          int err = get_errno (session);

          _gnutls_read_log ("READ: %d returned from %p, errno=%d gerrno=%d\n",
                            (int) i, fd, errno, session->internals.errnum);

          if (err == EAGAIN || err == EINTR)
            {
              if (size - left > 0)
                {

                  _gnutls_read_log ("READ: returning %d bytes from %p\n",
                                    (int) (size - left), fd);

                  goto finish;
                }

              if (err == EAGAIN)
                return GNUTLS_E_AGAIN;
              return GNUTLS_E_INTERRUPTED;
            }
          else
            {
              gnutls_assert ();
              return GNUTLS_E_PULL_ERROR;
            }
        }
      else
        {

          _gnutls_read_log ("READ: Got %d bytes from %p\n", (int) i, fd);

          if (i == 0)
            break;              /* EOF */
        }

      left -= i;
      (*bufel)->msg.size += i;
    }

finish:

  _gnutls_read_log ("READ: read %d bytes from %p\n",
                        (int) (size - left), fd);

  return (size - left);
}
Exemplo n.º 5
0
int pthread_cond_timedwait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex,
                           FAR const struct timespec *abstime)
{
    FAR struct tcb_s *rtcb = (FAR struct tcb_s *)g_readytorun.head;
    int ticks;
    int mypid = (int)getpid();
    irqstate_t int_state;
    int ret = OK;
    int status;

    sdbg("cond=0x%p mutex=0x%p abstime=0x%p\n", cond, mutex, abstime);

    DEBUGASSERT(rtcb->waitdog == NULL);

    /* Make sure that non-NULL references were provided. */

    if (!cond || !mutex)
    {
        ret = EINVAL;
    }

    /* Make sure that the caller holds the mutex */

    else if (mutex->pid != mypid)
    {
        ret = EPERM;
    }

    /* If no wait time is provided, this function degenerates to
     * the same behavior as pthread_cond_wait().
     */

    else if (!abstime)
    {
        ret = pthread_cond_wait(cond, mutex);
    }

    else
    {
        /* Create a watchdog */

        rtcb->waitdog = wd_create();
        if (!rtcb->waitdog)
        {
            ret = EINVAL;
        }
        else
        {
            sdbg("Give up mutex...\n");

            /* We must disable pre-emption and interrupts here so that
             * the time stays valid until the wait begins.   This adds
             * complexity because we assure that interrupts and
             * pre-emption are re-enabled correctly.
             */

            sched_lock();
            int_state = irqsave();

            /* Convert the timespec to clock ticks.  We must disable pre-emption
             * here so that this time stays valid until the wait begins.
             */

            ret = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
            if (ret)
            {
                /* Restore interrupts  (pre-emption will be enabled when
                 * we fall through the if/then/else
                 */

                irqrestore(int_state);
            }
            else
            {
                /* Check the absolute time to wait.  If it is now or in the past, then
                 * just return with the timedout condition.
                 */

                if (ticks <= 0)
                {
                    /* Restore interrupts and indicate that we have already timed out.
                     * (pre-emption will be enabled when we fall through the
                     * if/then/else
                     */

                    irqrestore(int_state);
                    ret = ETIMEDOUT;
                }
                else
                {
                    /* Give up the mutex */

                    mutex->pid = 0;
                    ret = pthread_givesemaphore((sem_t*)&mutex->sem);
                    if (ret)
                    {
                        /* Restore interrupts  (pre-emption will be enabled when
                         * we fall through the if/then/else)
                         */

                        irqrestore(int_state);
                    }
                    else
                    {
                        /* Start the watchdog */

                        wd_start(rtcb->waitdog, ticks, (wdentry_t)pthread_condtimedout,
                                 2, (uint32_t)mypid, (uint32_t)SIGCONDTIMEDOUT);

                        /* Take the condition semaphore.  Do not restore interrupts
                         * until we return from the wait.  This is necessary to
                         * make sure that the watchdog timer and the condition wait
                         * are started atomically.
                         */

                        status = sem_wait((sem_t*)&cond->sem);

                        /* Did we get the condition semaphore. */

                        if (status != OK)
                        {
                            /* NO.. Handle the special case where the semaphore wait was
                             * awakened by the receipt of a signal -- presumably the
                             * signal posted by pthread_condtimedout().
                             */

                            if (get_errno() == EINTR)
                            {
                                sdbg("Timedout!\n");
                                ret = ETIMEDOUT;
                            }
                            else
                            {
                                ret = EINVAL;
                            }
                        }

                        /* The interrupts stay disabled until after we sample the errno.
                         * This is because when debug is enabled and the console is used
                         * for debug output, then the errno can be altered by interrupt
                         * handling! (bad)
                         */

                        irqrestore(int_state);
                    }

                    /* Reacquire the mutex (retaining the ret). */

                    sdbg("Re-locking...\n");
                    status = pthread_takesemaphore((sem_t*)&mutex->sem);
                    if (!status)
                    {
                        mutex->pid = mypid;
                    }
                    else if (!ret)
                    {
                        ret = status;
                    }
                }

                /* Re-enable pre-emption (It is expected that interrupts
                 * have already been re-enabled in the above logic)
                 */

                sched_unlock();
            }

            /* We no longer need the watchdog */

            wd_delete(rtcb->waitdog);
            rtcb->waitdog = NULL;
        }
    }

    sdbg("Returning %d\n", ret);
    return ret;
}
Exemplo n.º 6
0
int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp)
{
  irqstate_t flags;
  systime_t starttick;
  sigset_t set;
  struct siginfo value;
  int errval;
#ifdef CONFIG_DEBUG /* Warning avoidance */
  int ret;
#endif

  if (!rqtp || rqtp->tv_nsec < 0 || rqtp->tv_nsec >= 1000000000)
    {
      errval = EINVAL;
      goto errout;
    }

  /* Get the start time of the wait.  Interrupts are disabled to prevent
   * timer interrupts while we do tick-related calculations before and
   * after the wait.
   */

  flags     = irqsave();
  starttick = clock_systimer();

  /* Set up for the sleep.  Using the empty set means that we are not
   * waiting for any particular signal.  However, any unmasked signal can
   * still awaken sigtimedwait().
   */

  (void)sigemptyset(&set);

  /* nanosleep is a simple application of sigtimedwait. */

#ifdef CONFIG_DEBUG /* Warning avoidance */
  ret = sigtimedwait(&set, &value, rqtp);
#else
  (void)sigtimedwait(&set, &value, rqtp);
#endif

  /* sigtimedwait() cannot succeed.  It should always return error with
   * either (1) EAGAIN meaning that the timeout occurred, or (2) EINTR
   * meaning that some other unblocked signal was caught.
   */

  errval = get_errno();
  DEBUGASSERT(ret < 0 && (errval == EAGAIN || errval == EINTR));

  if (errval == EAGAIN)
    {
      /* The timeout "error" is the normal, successful result */

      irqrestore(flags);
      return OK;
    }

  /* If we get there, the wait has failed because we were awakened by a
   * signal.  Return the amount of "unwaited" time if rmtp is non-NULL.
   */

  if (rmtp)
    {
      systime_t elapsed;
      systime_t remaining;
      int ticks;

      /* First get the number of clock ticks that we were requested to
       * wait.
       */

      (void)clock_time2ticks(rqtp, &ticks);

      /* Get the number of ticks that we actually waited */

      elapsed = clock_systimer() - starttick;

      /* The difference between the number of ticks that we were requested
       * to wait and the number of ticks that we actualy waited is that
       * amount of time that we failed to wait.
       */

      if (elapsed >= (uint32_t)ticks)
        {
          remaining = 0;
        }
      else
        {
          remaining = (uint32_t)ticks - elapsed;
        }

      (void)clock_ticks2time((int)remaining, rmtp);
    }

  irqrestore(flags);

errout:
  set_errno(errval);
  return ERROR;
}
Exemplo n.º 7
0
static FAR struct iob_s *iob_allocwait(bool throttled)
{
  FAR struct iob_s *iob;
  irqstate_t flags;
  FAR sem_t *sem;
  int ret = OK;

#if CONFIG_IOB_THROTTLE > 0
  /* Select the semaphore count to check. */

  sem = (throttled ? &g_throttle_sem : &g_iob_sem);
#else
  sem = &g_iob_sem;
#endif

  /* The following must be atomic; interrupt must be disabled so that there
   * is no conflict with interrupt level I/O buffer allocations.  This is
   * not as bad as it sounds because interrupts will be re-enabled while
   * we are waiting for I/O buffers to become free.
   */

  flags = irqsave();
  do
    {
      /* Try to get an I/O buffer.  If successful, the semaphore count
       * will be decremented atomically.
       */

      iob = iob_tryalloc(throttled);
      if (!iob)
        {
          /* If not successful, then the semaphore count was less than or
           * equal to zero (meaning that there are no free buffers).  We
           * need to wait for an I/O buffer to be released when the semaphore
           * count will be incremented.
           */

          ret = sem_wait(sem);
          if (ret < 0)
            {
              int errcode = get_errno();

              /* EINTR is not an error!  EINTR simply means that we were
               * awakened by a signal and we should try again.
               *
               * REVISIT:  Many end-user interfaces are required to return
               * with an error if EINTR is set.  Most uses of this function
               * is in internal, non-user logic.  But are there cases where
               * the error should be returned.
               */

              if (errcode == EINTR)
                {
                  /* Force a success indication so that we will continue
                   * looping.
                   */

                  ret = 0;
                }
              else
                {
                  /* Stop the loop and return a error */

                  DEBUGASSERT(errcode > 0);
                  ret = -errcode;
                }
            }
          else
            {
              /* When we wake up from wait successfully, an I/O buffer was
               * returned to the free list.  However, if there are concurrent
               * allocations from interrupt handling, then I suspect that
               * there is a race condition.  But no harm, we will just wait
               * again in that case.
               *
               * We need release our count so that it is available to
               * iob_tryalloc(), perhaps allowing another thread to take our
               * count.  In that event, iob_tryalloc() will fail above and
               * we will have to wait again.
               *
               * TODO: Consider a design modification to permit us to
               * complete the allocation without losing our count.
               */

              sem_post(sem);
            }
        }
    }
  while (ret == OK && iob == NULL);

  irqrestore(flags);
  return iob;
}
Exemplo n.º 8
0
long do_open(char * arg1, uint32_t arg2, uint32_t arg3)
{
    /* XXX: don't let the %s stay in there */
    DPRINTF("open(%s, 0x%x, 0x%x)\n", arg1, arg2, arg3);
    return get_errno(open(arg1, arg2, arg3));
}
Exemplo n.º 9
0
/* ??? Implement proper locking for ioctls.  */
static long do_ioctl(long fd, long cmd, long arg)
{
    const IOCTLEntry *ie;
    const argtype *arg_type;
    int ret;
    uint8_t buf_temp[MAX_STRUCT_SIZE];
    int target_size;
    void *argptr;

    ie = ioctl_entries;
    for(;;) {
        if (ie->target_cmd == 0) {
            gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd);
            return -ENOSYS;
        }
        if (ie->target_cmd == cmd)
            break;
        ie++;
    }
    arg_type = ie->arg_type;
#if defined(DEBUG)
    gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name);
#endif
    switch(arg_type[0]) {
    case TYPE_NULL:
        /* no argument */
        ret = get_errno(ioctl(fd, ie->host_cmd));
        break;
    case TYPE_PTRVOID:
    case TYPE_INT:
        /* int argment */
        ret = get_errno(ioctl(fd, ie->host_cmd, arg));
        break;
    case TYPE_PTR:
        arg_type++;
        target_size = thunk_type_size(arg_type, 0);
        switch(ie->access) {
        case IOC_R:
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
            if (!is_error(ret)) {
                argptr = lock_user(arg, target_size, 0);
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                unlock_user(argptr, arg, target_size);
            }
            break;
        case IOC_W:
            argptr = lock_user(arg, target_size, 1);
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
            unlock_user(argptr, arg, 0);
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
            break;
        default:
        case IOC_RW:
            argptr = lock_user(arg, target_size, 1);
            thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
            unlock_user(argptr, arg, 0);
            ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
            if (!is_error(ret)) {
                argptr = lock_user(arg, target_size, 0);
                thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
                unlock_user(argptr, arg, target_size);
            }
            break;
        }
        break;
    default:
        gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]);
        ret = -ENOSYS;
        break;
    }
    return ret;
}
Exemplo n.º 10
0
	s32 setsockopt(s32 s, s32 level, s32 optname, vm::cptr<void> optval, u32 optlen)
	{
		libnet.warning("setsockopt(s=%d, level=%d, optname=%d, optval=*0x%x, optlen=%d)", s, level, optname, optval, optlen);
		std::shared_ptr<sys_net_socket> sock = idm::get<sys_net_socket>(s);

		if (!sock)
		{
			libnet.error("setsockopt(): socket does not exist");
			return -1;
		}

		if (level != SOL_SOCKET && level != IPPROTO_TCP)
		{
			fmt::throw_exception("Invalid socket option level!" HERE);
		}

		s32 ret;

#ifdef _WIN32
		if (level == SOL_SOCKET)
		{
			switch (optname)
			{
			case OP_SO_NBIO:
			{
				unsigned long mode = *(unsigned long*)optval.get_ptr();
				ret = ioctlsocket(sock->s, FIONBIO, &mode);
				break;
			}
			case OP_SO_SNDBUF:
			{
				u32 sendbuff = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_SNDBUF, (const char*)&sendbuff, sizeof(sendbuff));
				break;
			}
			case OP_SO_RCVBUF:
			{
				u32 recvbuff = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_RCVBUF, (const char*)&recvbuff, sizeof(recvbuff));
				break;
			}
			case OP_SO_SNDTIMEO:
			{
				u32 sendtimeout = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_SNDTIMEO, (char*)&sendtimeout, sizeof(sendtimeout));
				break;
			}
			case OP_SO_RCVTIMEO:
			{
				u32 recvtimeout = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_RCVTIMEO, (char*)&recvtimeout, sizeof(recvtimeout));
				break;
			}
			case OP_SO_SNDLOWAT:
			{
				u32 sendlowmark = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_SNDLOWAT, (char*)&sendlowmark, sizeof(sendlowmark));
				break;
			}
			case OP_SO_RCVLOWAT:
			{
				u32 recvlowmark = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_RCVLOWAT, (char*)&recvlowmark, sizeof(recvlowmark));
				break;
			}
			case  OP_SO_USECRYPTO:
			{
				libnet.warning("Socket option OP_SO_USECRYPTO is unimplemented");
				break;
			}
			case  OP_SO_USESIGNATURE:
			{
				libnet.warning("Socket option OP_SO_USESIGNATURE is unimplemented");
				break;
			}
			case OP_SO_BROADCAST:
			{
				u32 enablebroadcast = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_BROADCAST, (char*)&enablebroadcast, sizeof(enablebroadcast));
				break;
			}
			case OP_SO_REUSEADDR:
			{
				u32 reuseaddr = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr));
				break;
			}
			default:
				libnet.error("Unknown socket option for Win32: 0x%x", optname);
			}
		}
		else if (level == PROTO_IPPROTO_TCP)
		{
			switch (optname)
			{
			case OP_TCP_NODELAY:
			{
				const char delay = *(char*)optval.get_ptr();
				ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_NODELAY, &delay, sizeof(delay));
				break;
			}

			case OP_TCP_MAXSEG:
			{
				libnet.warning("TCP_MAXSEG can't be set on Windows.");
				break;
			}

			default:
				libnet.error("Unknown TCP option for Win32: 0x%x", optname);
			}
		}
#else
		if (level == SOL_SOCKET)
		{
			switch (optname)
			{
			case OP_SO_NBIO:
			{
				// Obtain the flags
				s32 flags = fcntl(s, F_GETFL, 0);

				if (flags < 0)
				{
					fmt::throw_exception("Failed to obtain socket flags." HERE);
				}

				u32 mode = *(u32*)optval.get_ptr();
				flags = mode ? (flags &~O_NONBLOCK) : (flags | O_NONBLOCK);

				// Re-set the flags
				ret = fcntl(sock->s, F_SETFL, flags);
				break;
			}

			default:
				libnet.error("Unknown socket option for Unix: 0x%x", optname);
			}
		}
		else if (level == PROTO_IPPROTO_TCP)
		{
			switch (optname)
			{
			case OP_TCP_NODELAY:
			{
				u32 delay = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_NODELAY, &delay, optlen);
				break;
			}

			case OP_TCP_MAXSEG:
			{
				u32 maxseg = *(u32*)optval.get_ptr();
				ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_MAXSEG, &maxseg, optlen);
				break;
			}

			default:
				libnet.error("Unknown TCP option for Unix: 0x%x", optname);
			}
		}
#endif

		if (ret != 0)
		{
			libnet.error("setsockopt(): error %d", get_errno() = get_last_error());
			return -1;
		}

		return ret;
	}
Exemplo n.º 11
0
	vm::ptr<s32> _sys_net_errno_loc()
	{
		libnet.warning("_sys_net_errno_loc()");
		return get_errno().ptr();
	}
Exemplo n.º 12
0
int select(int nfds, FAR fd_set *readfds, FAR fd_set *writefds,
           FAR fd_set *exceptfds, FAR struct timeval *timeout)
{
  struct pollfd *pollset;
  int errcode = OK;
  int fd;
  int npfds;
  int msec;
  int ndx;
  int ret;

  /* select() is cancellation point */

  (void)enter_cancellation_point();

  /* How many pollfd structures do we need to allocate? */

  /* Initialize the descriptor list for poll() */

  for (fd = 0, npfds = 0; fd < nfds; fd++)
    {
      /* Check if any monitor operation is requested on this fd */

      if ((readfds   && FD_ISSET(fd, readfds))  ||
          (writefds  && FD_ISSET(fd, writefds)) ||
          (exceptfds && FD_ISSET(fd, exceptfds)))
        {
          /* Yes.. increment the count of pollfds structures needed */

          npfds++;
        }
    }

  /* Allocate the descriptor list for poll() */

  pollset = (struct pollfd *)kmm_zalloc(npfds * sizeof(struct pollfd));
  if (!pollset)
    {
      set_errno(ENOMEM);
      leave_cancellation_point();
      return ERROR;
    }

  /* Initialize the descriptor list for poll() */

  for (fd = 0, ndx = 0; fd < nfds; fd++)
    {
      int incr = 0;

      /* The readfs set holds the set of FDs that the caller can be assured
       * of reading from without blocking.  Note that POLLHUP is included as
       * a read-able condition.  POLLHUP will be reported at the end-of-file
       * or when a connection is lost.  In either case, the read() can then
       * be performed without blocking.
       */

      if (readfds && FD_ISSET(fd, readfds))
        {
          pollset[ndx].fd      = fd;
          pollset[ndx].events |= POLLIN;
          incr                 = 1;
        }

      /* The writefds set holds the set of FDs that the caller can be assured
       * of writing to without blocking.
       */

      if (writefds && FD_ISSET(fd, writefds))
        {
          pollset[ndx].fd      = fd;
          pollset[ndx].events |= POLLOUT;
          incr                 = 1;
        }

      /* The exceptfds set holds the set of FDs that are watched for exceptions */

      if (exceptfds && FD_ISSET(fd, exceptfds))
        {
          pollset[ndx].fd      = fd;
          incr                  = 1;
        }

      ndx += incr;
    }

  DEBUGASSERT(ndx == npfds);

  /* Convert the timeout to milliseconds */

  if (timeout)
    {
      /* Calculate the timeout in milliseconds */

      msec = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
    }
  else
    {
      /* Any negative value of msec means no timeout */

      msec = -1;
    }

  /* Then let poll do all of the real work. */

  ret = poll(pollset, npfds, msec);
  if (ret < 0)
    {
      /* poll() failed! Save the errno value */

      errcode = get_errno();
    }

  /* Now set up the return values */

  if (readfds)
    {
      memset(readfds, 0, sizeof(fd_set));
    }

  if (writefds)
    {
      memset(writefds, 0, sizeof(fd_set));
    }

  if (exceptfds)
    {
      memset(exceptfds, 0, sizeof(fd_set));
    }

  /* Convert the poll descriptor list back into selects 3 bitsets */

  if (ret > 0)
    {
      ret = 0;
      for (ndx = 0; ndx < npfds; ndx++)
        {
          /* Check for read conditions.  Note that POLLHUP is included as a
           * read condition.  POLLHUP will be reported when no more data will
           * be available (such as when a connection is lost).  In either
           * case, the read() can then be performed without blocking.
           */

          if (readfds)
            {
              if (pollset[ndx].revents & (POLLIN | POLLHUP))
                {
                  FD_SET(pollset[ndx].fd, readfds);
                  ret++;
                }
            }

          /* Check for write conditions */

          if (writefds)
            {
              if (pollset[ndx].revents & POLLOUT)
                {
                  FD_SET(pollset[ndx].fd, writefds);
                  ret++;
                }
            }

          /* Check for exceptions */

          if (exceptfds)
            {
              if (pollset[ndx].revents & POLLERR)
                {
                  FD_SET(pollset[ndx].fd, exceptfds);
                  ret++;
                }
            }
        }
    }

  kmm_free(pollset);

  /* Did poll() fail above? */

  if (ret < 0)
    {
      /* Yes.. restore the errno value */

      set_errno(errcode);
    }

  leave_cancellation_point();
  return ret;
}
Exemplo n.º 13
0
int lib_hostfile_lookup(FAR const void *addr, socklen_t len, int type,
                        FAR struct hostent *host, FAR char *buf,
                        size_t buflen, int *h_errnop)
{
  FAR FILE *stream;
  int herrnocode;
  int nread;

  /* Search the hosts file for a match */

  stream = fopen(CONFIG_NETDB_HOSTCONF_PATH, "r");
  if (stream == NULL)
    {
      int errcode = get_errno();

      nerr("ERROR:  Failed to open the hosts file %s: %d\n",
           CONFIG_NETDB_HOSTCONF_PATH, errcode);
      UNUSED(errcode);

      herrnocode = NO_RECOVERY;
      goto errorout_with_herrnocode;
    }

  /* Loop reading entries from the hosts file until a match is found or
   * until we hit the end-of-file.
   */

  do
    {
      /* Read the next entry from the hosts file */

      nread = lib_parse_hostfile(stream, host, buf, buflen);
      if (nread < 0)
        {
          /* Possible errors:
           *     ERANGE - Buffer not big enough
           *     ESPIPE - End of file (or possibly a read error).
           *     EAGAIN - Error parsing the line (E.g., missing hostname)
           */

          if (nread == -ESPIPE)
            {
              nread = 0;
            }
          else if (nread != -EAGAIN)
            {
              herrnocode = NO_RECOVERY;
              goto errorout_with_stream;
            }
        }
      else if (nread > 0 && len == host->h_length && type == host->h_addrtype)
        {
          /* We successfully read the entry and the type and size of the
           * address is good.  Now compare the addresses:
           */

          FAR char *hostaddr = host->h_addr;
          if (hostaddr != NULL)
            {
              ninfo("Comparing addresses...\n");
              if (memcmp(addr, hostaddr, len) == 0)
                {
                   /* We have a match */

                  fclose(stream);
                  return OK;
                }
            }
        }
    }
  while (nread != 0);

  /* We get here when the end of the hosts file is encountered without
   * finding the hostname.
   */

  herrnocode = HOST_NOT_FOUND;

errorout_with_stream:
  fclose(stream);

errorout_with_herrnocode:
  if (h_errnop)
    {
      *h_errnop = herrnocode;
    }

  return ERROR;
}
Exemplo n.º 14
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;

  svdbg("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();

      sdbg("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();
      sdbg("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)
     {
       sdbg("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;
}
Exemplo n.º 15
0
bool ubgps_check_alp_file_validity(const char *filepath)
{
  bool ret = false;
  uint8_t buf[2];
  ssize_t rlen;
  int fd;

  fd = open(filepath, O_RDONLY);
  if (fd < 0)
    {
      dbg("could not open file: \"%s\" (errno=%d)\n", filepath, get_errno());
      goto out;
    }

  /* Get header */

  rlen = read(fd, buf, 2);
  if (rlen < 2)
    {
      dbg("could not read header, rlen=%d, errno=%d\n", rlen, get_errno());
      goto out;
    }

  /* Expected header is 'µB' */

  if (!(buf[0] == 0xB5 && buf[1] == 0x62))
    {
      dbg("invalid header, %02X:%02X\n", buf[0], buf[1]);
      goto out;
    }

#if 0
  /* Get tail */

  rlen = lseek(fd, -2, SEEK_END);
  if (rlen == -1)
    {
      dbg("could not seek to tail, rlen=%d, errno=%d\n", rlen, get_errno());
      goto out;
    }

  rlen = read(fd, buf, 2);
  if (rlen < 2)
    {
      dbg("could not read tail, rlen=%d, errno=%d\n", rlen, get_errno());
      goto out;
    }

  /* Expected tail is 'XX' */

  if (!(buf[0] == 'X' && buf[1] == 'X'))
    {
      dbg("invalid tail, %02X:%02X\n", buf[0], buf[1]);
      goto out;
    }
#endif

  /* ALP file appears to be valid. */

  ret = true;

out:
  if (fd >= 0)
    {
      close(fd);
    }
  return ret;
}
Exemplo n.º 16
0
int sam_ajoy_initialization(void)
{
  int ret;
  int fd;
  int i;

  /* Initialize ADC.  We will need this to read the ADC inputs */

  ret = board_adc_initialize();
  if (ret < 0)
    {
      ierr("ERROR: board_adc_initialize() failed: %d\n", ret);
      return ret;
    }

  /* Open the ADC driver for reading. */

  fd = open("/dev/adc0", O_RDONLY);
  if (fd < 0)
    {
      int errcode = get_errno();
      ierr("ERROR: Failed to open /dev/adc0: %d\n", errcode);
      return -errcode;
    }

  /* Detach the file structure from the file descriptor so that it can be
   * used on any thread.
   */

  ret = file_detach(fd, &g_adcfile);
  if (ret < 0)
    {
      ierr("ERROR: Failed to detach from file descriptor: %d\n", ret);
      (void)close(fd);
      return ret;
    }

  /* Configure the GPIO pins as interrupting inputs. */

  for (i = 0; i < AJOY_NGPIOS; i++)
    {
      /* Configure the PIO as an input */

      sam_configpio(g_joypio[i]);

      /* Configure PIO interrupts, attach the interrupt handler, but leave
       * the interrupt disabled.
       */

      sam_pioirq(g_joypio[i]);
      (void)irq_attach(g_joyirq[i], ajoy_interrupt);
      sam_pioirqdisable(g_joyirq[i]);
    }

  /* Register the joystick device as /dev/ajoy0 */

  ret = ajoy_register("/dev/ajoy0", &g_ajoylower);
  if (ret < 0)
    {
      ierr("ERROR: ajoy_register failed: %d\n", ret);
      file_close_detached(&g_adcfile);
    }

  return ret;
}
Exemplo n.º 17
0
int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
                   pthread_startroutine_t start_routine, pthread_addr_t arg)
{
  FAR struct pthread_tcb_s *ptcb;
  FAR struct join_s *pjoin;
  struct sched_param param;
  int policy;
  int errcode;
  pid_t pid;
  int ret;
#ifdef HAVE_TASK_GROUP
  bool group_joined = false;
#endif

  /* If attributes were not supplied, use the default attributes */

  if (!attr)
    {
      attr = &g_default_pthread_attr;
    }

  /* Allocate a TCB for the new task. */

  ptcb = (FAR struct pthread_tcb_s *)kmm_zalloc(sizeof(struct pthread_tcb_s));
  if (!ptcb)
    {
      sdbg("ERROR: Failed to allocate TCB\n");
      return ENOMEM;
    }

#ifdef HAVE_TASK_GROUP
  /* Bind the parent's group to the new TCB (we have not yet joined the
   * group).
   */

  ret = group_bind(ptcb);
  if (ret < 0)
    {
      errcode = ENOMEM;
      goto errout_with_tcb;
    }
#endif

#ifdef CONFIG_ARCH_ADDRENV
  /* Share the address environment of the parent task group. */

  ret = up_addrenv_attach(ptcb->cmn.group,
                          (FAR struct tcb_s *)g_readytorun.head);
  if (ret < 0)
    {
      errcode = -ret;
      goto errout_with_tcb;
    }
#endif

  /* Allocate a detachable structure to support pthread_join logic */

  pjoin = (FAR struct join_s *)kmm_zalloc(sizeof(struct join_s));
  if (!pjoin)
    {
      sdbg("ERROR: Failed to allocate join\n");
      errcode = ENOMEM;
      goto errout_with_tcb;
    }

  /* Allocate the stack for the TCB */

  ret = up_create_stack((FAR struct tcb_s *)ptcb, attr->stacksize,
                        TCB_FLAG_TTYPE_PTHREAD);
  if (ret != OK)
    {
      errcode = ENOMEM;
      goto errout_with_join;
    }

  /* Should we use the priority and scheduler specified in the pthread
   * attributes?  Or should we use the current thread's priority and
   * scheduler?
   */

  if (attr->inheritsched == PTHREAD_INHERIT_SCHED)
    {
      /* Get the priority (and any other scheduling parameters) for this
       * thread.
       */

      ret = sched_getparam(0, &param);
      if (ret == ERROR)
        {
          errcode = get_errno();
          goto errout_with_join;
        }

      /* Get the scheduler policy for this thread */

      policy = sched_getscheduler(0);
      if (policy == ERROR)
        {
          errcode = get_errno();
          goto errout_with_join;
        }
    }
  else
    {
      /* Use the scheduler policy and policy the attributes */

      policy                             = attr->policy;
      param.sched_priority               = attr->priority;

#ifdef CONFIG_SCHED_SPORADIC
      param.sched_ss_low_priority        = attr->low_priority;
      param.sched_ss_max_repl            = attr->max_repl;
      param.sched_ss_repl_period.tv_sec  = attr->repl_period.tv_sec;
      param.sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec;
      param.sched_ss_init_budget.tv_sec  = attr->budget.tv_sec;
      param.sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec;
#endif
    }

#ifdef CONFIG_SCHED_SPORADIC
  if (policy == SCHED_SPORADIC)
    {
      FAR struct sporadic_s *sporadic;
      int repl_ticks;
      int budget_ticks;

      /* Convert timespec values to system clock ticks */

      (void)clock_time2ticks(&param.sched_ss_repl_period, &repl_ticks);
      (void)clock_time2ticks(&param.sched_ss_init_budget, &budget_ticks);

      /* The replenishment period must be greater than or equal to the
       * budget period.
       */

      if (repl_ticks < budget_ticks)
        {
          errcode = EINVAL;
          goto errout_with_join;
        }

      /* Initialize the sporadic policy */

      ret = sched_sporadic_initialize(&ptcb->cmn);
      if (ret >= 0)
        {
          sporadic               = ptcb->cmn.sporadic;
          DEBUGASSERT(sporadic != NULL);

          /* Save the sporadic scheduling parameters */

          sporadic->hi_priority  = param.sched_priority;
          sporadic->low_priority = param.sched_ss_low_priority;
          sporadic->max_repl     = param.sched_ss_max_repl;
          sporadic->repl_period  = repl_ticks;
          sporadic->budget       = budget_ticks;

          /* And start the first replenishment interval */

          ret = sched_sporadic_start(&ptcb->cmn);
        }

      /* Handle any failures */

      if (ret < 0)
        {
          errcode = -ret;
          goto errout_with_join;
        }
    }
#endif

  /* Initialize the task control block */

  ret = pthread_schedsetup(ptcb, param.sched_priority, pthread_start,
                           start_routine);
  if (ret != OK)
    {
      errcode = EBUSY;
      goto errout_with_join;
    }

  /* Configure the TCB for a pthread receiving on parameter
   * passed by value
   */

  pthread_argsetup(ptcb, arg);

#ifdef HAVE_TASK_GROUP
  /* Join the parent's task group */

  ret = group_join(ptcb);
  if (ret < 0)
    {
      errcode = ENOMEM;
      goto errout_with_join;
    }

  group_joined = true;
#endif

  /* Attach the join info to the TCB. */

  ptcb->joininfo = (FAR void *)pjoin;

  /* Set the appropriate scheduling policy in the TCB */

  ptcb->cmn.flags &= ~TCB_FLAG_POLICY_MASK;
  switch (policy)
    {
      default:
        DEBUGPANIC();
      case SCHED_FIFO:
        ptcb->cmn.flags    |= TCB_FLAG_SCHED_FIFO;
        break;

#if CONFIG_RR_INTERVAL > 0
      case SCHED_RR:
        ptcb->cmn.flags    |= TCB_FLAG_SCHED_RR;
        ptcb->cmn.timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
        break;
#endif

#ifdef CONFIG_SCHED_SPORADIC
      case SCHED_SPORADIC:
        ptcb->cmn.flags    |= TCB_FLAG_SCHED_SPORADIC;
        break;
#endif

#if 0 /* Not supported */
      case SCHED_OTHER:
        ptcb->cmn.flags    |= TCB_FLAG_SCHED_OTHER;
        break;
#endif
    }

  /* Get the assigned pid before we start the task (who knows what
   * could happen to ptcb after this!).  Copy this ID into the join structure
   * as well.
   */

  pid = (int)ptcb->cmn.pid;
  pjoin->thread = (pthread_t)pid;

  /* Initialize the semaphores in the join structure to zero. */

  ret = sem_init(&pjoin->data_sem, 0, 0);
  if (ret == OK)
    {
      ret = sem_init(&pjoin->exit_sem, 0, 0);
    }

  /* Activate the task */

  sched_lock();
  if (ret == OK)
    {
      ret = task_activate((FAR struct tcb_s *)ptcb);
    }

  if (ret == OK)
    {
      /* Wait for the task to actually get running and to register
       * its join structure.
       */

      (void)pthread_takesemaphore(&pjoin->data_sem);

      /* Return the thread information to the caller */

      if (thread)
       {
         *thread = (pthread_t)pid;
       }

      if (!pjoin->started)
        {
          ret = EINVAL;
        }

      sched_unlock();
      (void)sem_destroy(&pjoin->data_sem);
    }
  else
    {
      sched_unlock();
      dq_rem((FAR dq_entry_t *)ptcb, (FAR dq_queue_t *)&g_inactivetasks);
      (void)sem_destroy(&pjoin->data_sem);
      (void)sem_destroy(&pjoin->exit_sem);

      errcode = EIO;
      goto errout_with_join;
    }

  return ret;

errout_with_join:
  sched_kfree(pjoin);
  ptcb->joininfo = NULL;

errout_with_tcb:
#ifdef HAVE_TASK_GROUP
  /* Clear group binding */

  if (ptcb && !group_joined)
    {
      ptcb->cmn.group = NULL;
    }
#endif

  sched_releasetcb((FAR struct tcb_s *)ptcb, TCB_FLAG_TTYPE_PTHREAD);
  return errcode;
}
Exemplo n.º 18
0
Arquivo: syscall.c Projeto: JMR-b/qemu
/* do_syscall() should always have a single exit point at the end so
   that actions, such as logging of syscall results, can be performed.
   All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                            abi_long arg2, abi_long arg3, abi_long arg4,
                            abi_long arg5, abi_long arg6, abi_long arg7,
                            abi_long arg8)
{
    abi_long ret;
    void *p;

#ifdef DEBUG
    gemu_log("freebsd syscall %d\n", num);
#endif
    if(do_strace)
        print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);

    switch(num) {
    case TARGET_FREEBSD_NR_exit:
#ifdef TARGET_GPROF
        _mcleanup();
#endif
        gdb_exit(cpu_env, arg1);
        /* XXX: should free thread stack and CPU env */
        _exit(arg1);
        ret = 0; /* avoid warning */
        break;
    case TARGET_FREEBSD_NR_read:
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
            goto efault;
        ret = get_errno(read(arg1, p, arg3));
        unlock_user(p, arg2, ret);
        break;
    case TARGET_FREEBSD_NR_write:
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
            goto efault;
        ret = get_errno(write(arg1, p, arg3));
        unlock_user(p, arg2, 0);
        break;
    case TARGET_FREEBSD_NR_writev:
        {
            int count = arg3;
            struct iovec *vec;

            vec = alloca(count * sizeof(struct iovec));
            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
                goto efault;
            ret = get_errno(writev(arg1, vec, count));
            unlock_iovec(vec, arg2, count, 0);
        }
        break;
    case TARGET_FREEBSD_NR_open:
        if (!(p = lock_user_string(arg1)))
            goto efault;
        ret = get_errno(open(path(p),
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
                             arg3));
        unlock_user(p, arg1, 0);
        break;
    case TARGET_FREEBSD_NR_mmap:
        ret = get_errno(target_mmap(arg1, arg2, arg3,
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
                                    arg5,
                                    arg6));
        break;
    case TARGET_FREEBSD_NR_mprotect:
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
        break;
    case TARGET_FREEBSD_NR_break:
        ret = do_obreak(arg1);
        break;
#ifdef __FreeBSD__
    case TARGET_FREEBSD_NR___sysctl:
        ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6);
        break;
#endif
    case TARGET_FREEBSD_NR_sysarch:
        ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
        break;
    case TARGET_FREEBSD_NR_syscall:
    case TARGET_FREEBSD_NR___syscall:
        ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0);
        break;
    default:
        ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
        break;
    }
 fail:
#ifdef DEBUG
    gemu_log(" = %ld\n", ret);
#endif
    if (do_strace)
        print_freebsd_syscall_ret(num, ret);
    return ret;
 efault:
    ret = -TARGET_EFAULT;
    goto fail;
}
Exemplo n.º 19
0
int schedule_unload(pid_t pid, FAR struct binary_s *bin)
{
  struct sigaction act;
  struct sigaction oact;
  sigset_t sigset;
  irqstate_t flags;
  int errorcode;
  int ret;

  /* Make sure that SIGCHLD is unmasked */

  (void)sigemptyset(&sigset);
  (void)sigaddset(&sigset, SIGCHLD);
  ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
  if (ret != OK)
    {
      /* The errno value will get trashed by the following debug output */

      errorcode = get_errno();
      bvdbg("ERROR: sigprocmask failed: %d\n", ret);
      goto errout;
    }

  /* Add the structure to the list.  We want to do this *before* connecting
   * the signal handler.  This does, however, make error recovery more
   * complex if sigaction() fails below because then we have to remove the
   * unload structure for the list in an unexpected context.
   */

  unload_list_add(pid, bin);

  /* Register the SIGCHLD handler */

  act.sa_sigaction = unload_callback;
  act.sa_flags     = SA_SIGINFO;

  (void)sigfillset(&act.sa_mask);
  (void)sigdelset(&act.sa_mask, SIGCHLD);

  ret = sigaction(SIGCHLD, &act, &oact);
  if (ret != OK)
    {
      /* The errno value will get trashed by the following debug output */

      errorcode = get_errno();
      bvdbg("ERROR: sigaction failed: %d\n" , ret);

      /* Emergency removal from the list */

      flags = irqsave();
      if (unload_list_remove(pid) != bin)
        {
          blldbg("ERROR: Failed to remove structure\n");
        }
      
      goto errout;
    }

  return OK;

errout:
  set_errno(errorcode);
  return ERROR;
}
Exemplo n.º 20
0
Arquivo: syscall.c Projeto: JMR-b/qemu
abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                            abi_long arg2, abi_long arg3, abi_long arg4,
                            abi_long arg5, abi_long arg6)
{
    abi_long ret;
    void *p;

#ifdef DEBUG
    gemu_log("openbsd syscall %d\n", num);
#endif
    if(do_strace)
        print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);

    switch(num) {
    case TARGET_OPENBSD_NR_exit:
#ifdef TARGET_GPROF
        _mcleanup();
#endif
        gdb_exit(cpu_env, arg1);
        /* XXX: should free thread stack and CPU env */
        _exit(arg1);
        ret = 0; /* avoid warning */
        break;
    case TARGET_OPENBSD_NR_read:
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
            goto efault;
        ret = get_errno(read(arg1, p, arg3));
        unlock_user(p, arg2, ret);
        break;
    case TARGET_OPENBSD_NR_write:
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
            goto efault;
        ret = get_errno(write(arg1, p, arg3));
        unlock_user(p, arg2, 0);
        break;
    case TARGET_OPENBSD_NR_open:
        if (!(p = lock_user_string(arg1)))
            goto efault;
        ret = get_errno(open(path(p),
                             target_to_host_bitmask(arg2, fcntl_flags_tbl),
                             arg3));
        unlock_user(p, arg1, 0);
        break;
    case TARGET_OPENBSD_NR_mmap:
        ret = get_errno(target_mmap(arg1, arg2, arg3,
                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
                                    arg5,
                                    arg6));
        break;
    case TARGET_OPENBSD_NR_mprotect:
        ret = get_errno(target_mprotect(arg1, arg2, arg3));
        break;
    case TARGET_OPENBSD_NR_syscall:
    case TARGET_OPENBSD_NR___syscall:
        ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
        break;
    default:
        ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
        break;
    }
 fail:
#ifdef DEBUG
    gemu_log(" = %ld\n", ret);
#endif
    if (do_strace)
        print_openbsd_syscall_ret(num, ret);
    return ret;
 efault:
    ret = -TARGET_EFAULT;
    goto fail;
}
Exemplo n.º 21
0
static ssize_t
_gnutls_dgram_read (gnutls_session_t session, mbuffer_st **bufel,
		    gnutls_pull_func pull_func)
{
  ssize_t i, ret;
  char *ptr;
  size_t max_size = _gnutls_get_max_decrypted_data(session);
  size_t recv_size = MAX_RECV_SIZE(session);
  gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

  if (recv_size > max_size)
    recv_size = max_size;

  *bufel = _mbuffer_alloc (0, max_size);
  if (*bufel == NULL)
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

  ptr = (*bufel)->msg.data;

  session->internals.direction = 0;

  reset_errno (session);
  i = pull_func (fd, ptr, recv_size);

  if (i < 0)
    {
      int err = get_errno (session);

      _gnutls_read_log ("READ: %d returned from %p, errno=%d gerrno=%d\n",
			(int) i, fd, errno, session->internals.errnum);

      if (err == EAGAIN)
        {
          ret = GNUTLS_E_AGAIN;
          goto cleanup;
        }
      else if (err == EINTR)
        {
          ret = GNUTLS_E_INTERRUPTED;
          goto cleanup;
        }
      else
        {
          gnutls_assert ();
          ret = GNUTLS_E_PULL_ERROR;
          goto cleanup;
        }
    }
  else
    {
      _gnutls_read_log ("READ: Got %d bytes from %p\n", (int) i, fd);
      if (i == 0) 
        {
          /* If we get here, we likely have a stream socket.
           * FIXME: this probably breaks DCCP. */
          gnutls_assert ();
          ret = 0;
          goto cleanup;
        }

      _mbuffer_set_udata_size (*bufel, i);
    }

  _gnutls_read_log ("READ: read %d bytes from %p\n", (int) i, fd);
  
  return i;
  
cleanup:
  _mbuffer_xfree(bufel);
  return ret;
}
Exemplo n.º 22
0
static int ajoy_sample(FAR const struct ajoy_lowerhalf_s *lower,
                       FAR struct ajoy_sample_s *sample)
{
  struct adc_msg_s adcmsg[SAM_ADC_NCHANNELS];
  FAR struct adc_msg_s *ptr;
  ssize_t nread;
  ssize_t offset;
  int have;
  int i;

  /* Read all of the available samples (handling the case where additional
   * channels are enabled).
   */

  nread = file_read(&g_adcfile, adcmsg,
                    MAX_ADC_CHANNELS * sizeof(struct adc_msg_s));
  if (nread < 0)
    {
      int errcode = get_errno();
      if (errcode != EINTR)
        {
          ierr("ERROR: read failed: %d\n", errcode);
        }

      return -errcode;
    }
  else if (nread < 2 * sizeof(struct adc_msg_s))
    {
      ierr("ERROR: read too small: %ld\n", (long)nread);
      return -EIO;
    }

  /* Sample and the raw analog inputs */

  for (i = 0, offset = 0, have = 0;
       i < SAM_ADC_NCHANNELS && offset < nread && have != 3;
       i++, offset += sizeof(struct adc_msg_s))
    {
      ptr = &adcmsg[i];

      /* Is this one of the channels that we need? */

      if ((have & 1) == 0 && ptr->am_channel == 0)
        {
          int32_t tmp = ptr->am_data;
          sample->as_x = (int16_t)tmp;
          have |= 1;

          iinfo("X sample: %ld -> %d\n", (long)tmp, (int)sample->as_x);
        }

      if ((have & 2) == 0 && ptr->am_channel == 1)
        {
          int32_t tmp = ptr->am_data;
          sample->as_y = (int16_t)tmp;
          have |= 2;

          iinfo("Y sample: %ld -> %d\n", (long)tmp, (int)sample->as_y);
        }
    }

  if (have != 3)
    {
      ierr("ERROR: Could not find joystack channels\n");
      return -EIO;
    }


  /* Sample the discrete button inputs */

  sample->as_buttons = ajoy_buttons(lower);
  iinfo("Returning: %02x\n", AJOY_SUPPORTED);
  return OK;
}
Exemplo n.º 23
0
int read(int fid, void *buf, unsigned int nbytes)
{
  int hchar = 0, read = 0;
  FILE *file;

  /*-------------------------------------------------------------------*/
  /* If number of requested bytes is zero, return zero.                */
  /*-------------------------------------------------------------------*/
  if (nbytes == 0)
    return 0;

#if OS_PARM_CHECK
  /*-------------------------------------------------------------------*/
  /* Ensure file descriptor is valid.                                  */
  /*-------------------------------------------------------------------*/
  if (fid < 0 || fid >= FOPEN_MAX)
  {
    set_errno(EBADF);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* Return error if buffer pointer is invalid.                        */
  /*-------------------------------------------------------------------*/
  if (buf == NULL)
  {
    Files[fid].errcode = EFAULT;
    set_errno(EFAULT);
    return -1;
  }
#endif

  /*-------------------------------------------------------------------*/
  /* Acquire exclusive read access to file.                            */
  /*-------------------------------------------------------------------*/
  file = &Files[fid];
  file->acquire(file, F_READ);

  /*-------------------------------------------------------------------*/
  /* Return error if file is closed.                                   */
  /*-------------------------------------------------------------------*/
  if (file->ioctl == NULL)
  {
    set_errno(EBADF);
    file->release(file, F_READ);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* If available, read pushed-back character first.                   */
  /*-------------------------------------------------------------------*/
  if (file->hold_char)
  {
    ui8 *cp = buf;

    *cp = (ui8)file->hold_char;
    buf = cp + 1;
    file->hold_char = 0;
    hchar = 1;
    --nbytes;
  }

  /*-------------------------------------------------------------------*/
  /* Check if there are more characters to read.                       */
  /*-------------------------------------------------------------------*/
  if (nbytes)
  {
    /*-----------------------------------------------------------------*/
    /* Pass read request to file system or device driver.              */
    /*-----------------------------------------------------------------*/
    read = file->read(file, buf, nbytes);

    /*-----------------------------------------------------------------*/
    /* Read error is disregarded iff pushed-back character was read.   */
    /*-----------------------------------------------------------------*/
    if (read == -1)
    {
      if (hchar)
        read = 0;
      else
        file->errcode = get_errno();
    }
  }

  /*-------------------------------------------------------------------*/
  /* Release exclusive read access to file.                            */
  /*-------------------------------------------------------------------*/
  file->release(file, F_READ);

  /*-------------------------------------------------------------------*/
  /* Return number of bytes successfully read or -1.                   */
  /*-------------------------------------------------------------------*/
  return read + hchar;
}
Exemplo n.º 24
0
int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
{
  FAR struct tcb_s *rtcb = this_task();
  irqstate_t flags;
  int        ticks;
  int        errcode;
  int        ret = ERROR;

  DEBUGASSERT(up_interrupt_context() == false && rtcb->waitdog == NULL);

  /* Verify the input parameters and, in case of an error, set
   * errno appropriately.
   */

#ifdef CONFIG_DEBUG
  if (!abstime || !sem)
    {
      errcode = EINVAL;
      goto errout;
    }
#endif

  /* Create a watchdog.  We will not actually need this watchdog
   * unless the semaphore is unavailable, but we will reserve it up
   * front before we enter the following critical section.
   */

  rtcb->waitdog = wd_create();
  if (!rtcb->waitdog)
    {
      errcode = ENOMEM;
      goto errout;
    }

  /* We will disable interrupts until we have completed the semaphore
   * wait.  We need to do this (as opposed to just disabling pre-emption)
   * because there could be interrupt handlers that are asynchronously
   * posting semaphores and to prevent race conditions with watchdog
   * timeout.  This is not too bad because interrupts will be re-
   * enabled while we are blocked waiting for the semaphore.
   */

  flags = irqsave();

  /* Try to take the semaphore without waiting. */

  ret = sem_trywait(sem);
  if (ret == OK)
    {
      /* We got it! */

      goto success_with_irqdisabled;
    }

  /* We will have to wait for the semaphore.  Make sure that we were provided
   * with a valid timeout.
   */

  if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
    {
      errcode = EINVAL;
      goto errout_with_irqdisabled;
    }

  /* Convert the timespec to clock ticks.  We must have interrupts
   * disabled here so that this time stays valid until the wait begins.
   */

  errcode = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);

  /* If the time has already expired return immediately. */

  if (errcode == OK && ticks <= 0)
    {
      errcode = ETIMEDOUT;
      goto errout_with_irqdisabled;
    }

  /* Handle any time-related errors */

  if (errcode != OK)
    {
      goto errout_with_irqdisabled;
    }

  /* Start the watchdog */

  (void)wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid());

  /* Now perform the blocking wait */

  ret = sem_wait(sem);
  if (ret < 0)
    {
      /* sem_wait() failed.  Save the errno value */

      errcode = get_errno();
    }

  /* Stop the watchdog timer */

  wd_cancel(rtcb->waitdog);

  if (errcode != OK)
    {
      goto errout_with_irqdisabled;
    }

  /* We can now restore interrupts and delete the watchdog */

  /* Success exits */

success_with_irqdisabled:
  irqrestore(flags);
  wd_delete(rtcb->waitdog);
  rtcb->waitdog = NULL;
  return OK;

  /* Error exits */

errout_with_irqdisabled:
  irqrestore(flags);
  wd_delete(rtcb->waitdog);
  rtcb->waitdog = NULL;

errout:
  set_errno(errcode);
  return ERROR;
}
Exemplo n.º 25
0
int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
                     FAR socklen_t *addrlen, FAR void **newconn)
{
    FAR struct tcp_conn_s *conn;
    struct accept_s state;
    int ret;

    DEBUGASSERT(psock && newconn);

    /* Check the backlog to see if there is a connection already pending for
     * this listener.
     */

    conn = (FAR struct tcp_conn_s *)psock->s_conn;

#ifdef CONFIG_NET_TCPBACKLOG
    state.acpt_newconn = tcp_backlogremove(conn);
    if (state.acpt_newconn)
    {
        /* Yes... get the address of the connected client */

        nvdbg("Pending conn=%p\n", state.acpt_newconn);
        accept_tcpsender(psock, state.acpt_newconn, addr, addrlen);
    }

    /* In general, this uIP-based implementation will not support non-blocking
     * socket operations... except in a few cases:  Here for TCP accept with
     * backlog enabled.  If this socket is configured as non-blocking then
     * return EAGAIN if there is no pending connection in the backlog.
     */

    else if (_SS_ISNONBLOCK(psock->s_flags))
    {
        return -EAGAIN;
    }
    else
#endif
    {
        /* Set the socket state to accepting */

        psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_ACCEPT);

        /* Perform the TCP accept operation */

        /* Initialize the state structure.  This is done with interrupts
         * disabled because we don't want anything to happen until we
         * are ready.
         */

        state.acpt_sock       = psock;
        state.acpt_addr       = addr;
        state.acpt_addrlen    = addrlen;
        state.acpt_newconn    = NULL;
        state.acpt_result     = OK;
        sem_init(&state.acpt_sem, 0, 0);

        /* Set up the callback in the connection */

        conn->accept_private  = (FAR void *)&state;
        conn->accept          = accept_interrupt;

        /* Wait for the send to complete or an error to occur:  NOTES: (1)
         * net_lockedwait will also terminate if a signal is received, (2)
         * interrupts may be disabled!  They will be re-enabled while the
         * task sleeps and automatically re-enabled when the task restarts.
         */

        ret = net_lockedwait(&state.acpt_sem);
        if (ret < 0)
        {
            /* The value returned by net_lockedwait() the same as the value
             * returned by sem_wait():  Zero (OK) is returned on success; -1
             * (ERROR) is returned on a failure with the errno value set
             * appropriately.
             *
             * We have to preserve the errno value here because it may be
             * altered by intervening operations.
             */

            ret = -get_errno();
            DEBUGASSERT(ret < 0);
        }

        /* Make sure that no further interrupts are processed */

        conn->accept_private = NULL;
        conn->accept         = NULL;

        sem_destroy(&state. acpt_sem);

        /* Set the socket state to idle */

        psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

        /* Check for a errors.  Errors are signalled by negative errno values
         * for the send length.
         */

        if (state.acpt_result != 0)
        {
            DEBUGASSERT(state.acpt_result > 0);
            return -state.acpt_result;
        }

        /* If net_lockedwait failed, then we were probably reawakened by a
         * signal. In this case, logic above will have set 'ret' to the
         * errno value returned by net_lockedwait().
         */

        if (ret < 0)
        {
            return ret;
        }
    }

    *newconn = (FAR void *)state.acpt_newconn;
    return OK;
}
Exemplo n.º 26
0
ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
{
  FAR struct nxffs_volume_s *volume;
  FAR struct nxffs_wrfile_s *wrfile;
  ssize_t remaining;
  ssize_t nwritten;
  ssize_t total;
  int ret;

  fvdbg("Write %d bytes to offset %d\n", buflen, filep->f_pos);

  /* Sanity checks */

  DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);

  /* Recover the open file state from the struct file instance */

  wrfile = (FAR struct nxffs_wrfile_s *)filep->f_priv;

  /* Recover the volume state from the open file */

  volume = (FAR struct nxffs_volume_s *)filep->f_inode->i_private;
  DEBUGASSERT(volume != NULL);

  /* Get exclusive access to the volume.  Note that the volume exclsem
   * protects the open file list.
   */

  ret = sem_wait(&volume->exclsem);
  if (ret != OK)
    {
      ret = -get_errno();
      fdbg("ERROR: sem_wait failed: %d\n", ret);
      goto errout;
    }

  /* Check if the file was opened with write access */

  if ((wrfile->ofile.oflags & O_WROK) == 0)
    {
      fdbg("ERROR: File not open for write access\n");
      ret = -EACCES;
      goto errout_with_semaphore;
    }

  /* Loop until we successfully appended all of the data to the file (or an
   * error occurs)
   */

  for (total = 0; total < buflen; )
    {
      remaining = buflen - total;

      /* Have we already allocated the data block? */

      if (wrfile->doffset == 0)
        {
          /* No, allocate the data block now, re-packing if necessary. */

          wrfile->datlen = 0;
          ret = nxffs_wralloc(volume, wrfile, remaining);
          if (ret < 0)
            {
              fdbg("ERROR: Failed to allocate a data block: %d\n", -ret);
              goto errout_with_semaphore;
            }
        }

      /* Seek to the FLASH block containing the data block */

      nxffs_ioseek(volume, wrfile->doffset);

      /* Verify that the FLASH data that was previously written is still intact */

      ret = nxffs_reverify(volume, wrfile);
      if (ret < 0)
        {
          fdbg("ERROR: Failed to verify FLASH data block: %d\n", -ret);
          goto errout_with_semaphore;
        }

      /* Append the data to the end of the data block and write the updated
       * block to flash.
       */

      nwritten = nxffs_wrappend(volume, wrfile, &buffer[total], remaining);
      if (nwritten < 0)
        {
          fdbg("ERROR: Failed to append to FLASH to a data block: %d\n", -ret);
          goto errout_with_semaphore;
        }

      /* Decrement the number of bytes remaining to be written */

      total += nwritten;
    }

  /* Success.. return the number of bytes written */

  ret           = total;
  filep->f_pos  = wrfile->datlen;

errout_with_semaphore:
  sem_post(&volume->exclsem);
errout:
  return ret;
}
Exemplo n.º 27
0
static void
output_skeleton (void)
{
  FILE *m4_in = NULL;
  FILE *m4_out = NULL;
  char m4_in_file_name[] = "~m4_in_temp_file_XXXXXX";
  char m4_out_file_name[] = "~m4_out_temp_file_XXXXXX";
//  FILE *in;
//  int filter_fd[2];
  char const *argv[10];
//  pid_t pid;

  /* Compute the names of the package data dir and skeleton files.  */
  char const m4sugar[] = "m4sugar/m4sugar.m4";
  char const m4bison[] = "bison.m4";
  char *full_m4sugar;
  char *full_m4bison;
  char *full_skeleton;
  char const *p;
  char const *m4 = (p = getenv ("M4")) ? p : "M4";
  int i = 0;
  char const *pkgdatadir = compute_pkgdatadir ();
  size_t skeleton_size = strlen (skeleton) + 1;
  size_t pkgdatadirlen = strlen (pkgdatadir);
  while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
    pkgdatadirlen--;
  full_skeleton = xmalloc (pkgdatadirlen + 1
			   + (skeleton_size < sizeof m4sugar
			      ? sizeof m4sugar : skeleton_size));
  strncpy (full_skeleton, pkgdatadir, pkgdatadirlen);
  full_skeleton[pkgdatadirlen] = '/';
  strcpy (full_skeleton + pkgdatadirlen + 1, m4sugar);
  full_m4sugar = xstrdup (full_skeleton);
  strcpy (full_skeleton + pkgdatadirlen + 1, m4bison);
  full_m4bison = xstrdup (full_skeleton);
  if (_mbschr (skeleton, '/'))
    strcpy (full_skeleton, skeleton);
  else
    strcpy (full_skeleton + pkgdatadirlen + 1, skeleton);

  /* Test whether m4sugar.m4 is readable, to check for proper
     installation.  A faulty installation can cause deadlock, so a
     cheap sanity check is worthwhile.  */
  xfclose (xfopen (full_m4sugar, "r"));

  /* Create an m4 subprocess connected to us via two pipes.  */

  if (trace_flag & trace_tools)
    fprintf (stderr, "running: %s %s - %s %s\n",
             m4, full_m4sugar, full_m4bison, full_skeleton);

  /* Some future version of GNU M4 (most likely 1.6) may treat the -dV in a
     position-dependent manner.  Keep it as the first argument so that all
     files are traced.

     See the thread starting at
     <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
     for details.  */
  {
    argv[i++] = m4;

    /* When POSIXLY_CORRECT is set, GNU M4 1.6 and later disable GNU
       extensions, which Bison's skeletons depend on.  With older M4,
       it has no effect.  M4 1.4.12 added a -g/--gnu command-line
       option to make it explicit that a program wants GNU M4
       extensions even when POSIXLY_CORRECT is set.

       See the thread starting at
       <http://lists.gnu.org/archive/html/bug-bison/2008-07/msg00000.html>
       for details.  */
 //   if (*M4_GNU_OPTION)
 //     argv[i++] = M4_GNU_OPTION;

    argv[i++] = "-I";
    argv[i++] = pkgdatadir;
    if (trace_flag & trace_m4)
      argv[i++] = "-dV";
    argv[i++] = full_m4sugar;
    argv[i++] = "-";
    argv[i++] = full_m4bison;
    argv[i++] = full_skeleton;
    argv[i++] = NULL;
    aver (i <= ARRAY_CARDINALITY (argv));

    /* The ugly cast is because gnulib gets the const-ness wrong.  */
   // pid = create_pipe_bidi ("m4", m4, (char **)(void*)argv, false, true,
   //                         true, filter_fd);
  }


  if (trace_flag & trace_muscles)
    muscles_output (stderr);
  {
    m4_in = mkstempFILE(m4_in_file_name, "w+");
    if (!m4_in)
      error (EXIT_FAILURE, get_errno (),
             "fopen");
    muscles_output (m4_in);

	fflush(m4_in);
	if (fseek(m4_in, 0, SEEK_SET))
      error (EXIT_FAILURE, get_errno (),
             "fseek");
  }

  /* Read and process m4's output.  */
  {
    m4_out = mkstempFILE(m4_out_file_name, "w+");
    if (!m4_out)
      error (EXIT_FAILURE, get_errno (),
             "fopen");
  }

  if (main_m4(i-1, argv, m4_in, m4_out))
      error (EXIT_FAILURE, get_errno (),
             "m4 failed");


  free (full_m4sugar);
  free (full_m4bison);
  free (full_skeleton);

  fflush(m4_out);
  if (fseek(m4_out, 0, SEEK_SET))
    error (EXIT_FAILURE, get_errno (),
      "fseek");

  timevar_push (TV_M4);
//  in = fdopen (filter_fd[0], "r");
//  if (! in)
//    error (EXIT_FAILURE, get_errno (),
//	   "fdopen");
  scan_skel (m4_out);
    /* scan_skel should have read all of M4's output.  Otherwise, when we
       close the pipe, we risk letting M4 report a broken-pipe to the
       Bison user.  */
  aver (feof (m4_out));
  xfclose (m4_in);
  xfclose (m4_out);

  _unlink (m4_in_file_name);
  _unlink (m4_out_file_name);
//  wait_subprocess (pid, "m4", false, false, true, true, NULL);
  timevar_pop (TV_M4);
}
Exemplo n.º 28
0
/****************************************************************************
 * Name: ubgps_handle_aid_alpsrv
 *
 * Description:
 *   Handle AID-ALPSRV UBX message
 *
 * Input Parameters:
 *   gps         - GPS object
 *   msg         - UBX AID-ALPSRV message
 *
 * Returned Values:
 *   Status
 *
 ****************************************************************************/
int ubgps_handle_aid_alpsrv(struct ubgps_s * const gps, struct ubx_msg_s const * const msg)
{
  uint8_t requested_data_type;
  size_t data_offset;
  size_t data_size;
  ssize_t data_read;
  struct ubx_msg_s * resp = NULL;
  int alpfd = -1;
  int status = ERROR;
  int ret;

  DEBUGASSERT(gps && msg);

  if (!gps->assist)
    return OK;

  /* Check that AssistNow Offline data is available */

  ret = pthread_mutex_trylock(&g_aid_mutex);
  if (ret != 0)
    {
      dbg_int("mutex_trylock failed: %d\n", ret);
      return OK;
    }

  if (!gps->assist->alp_file || !gps->assist->alp_file_id)
    {
      pthread_mutex_unlock(&g_aid_mutex);
      return OK;
    }

  if (!ubgps_check_alp_file_validity(gps->assist->alp_file))
    {
      free(gps->assist->alp_file);
      gps->assist->alp_file = NULL;
      pthread_mutex_unlock(&g_aid_mutex);
      return OK;
    }

  requested_data_type = UBX_GET_U1(msg, 1);
  data_offset = (uint32_t)UBX_GET_U2(msg, 2) * 2;
  data_size = (uint32_t)UBX_GET_U2(msg, 4) * 2;

  dbg_int("file_id:%u, type:%u, offset:%u, size:%u\n",
      gps->assist->alp_file_id, requested_data_type, data_offset, data_size);

  /* Check if AID-ALPSRV is a download request */

  if (requested_data_type != 0xff)
    {
      /* Allocate response */

      resp = ubx_msg_allocate(UBX_CLASS_AID,
                              UBX_AID_ALPSRV,
                              UBX_AID_ALPSRV_LEN + data_size);
      if (!resp)
        goto errout;

      /* Copy original data to response */

      memcpy(&resp->payload[0], &msg->payload[0], UBX_AID_ALPSRV_LEN);

      /* Set ALP file ID */

      UBX_SET_U2(resp, 6, gps->assist->alp_file_id);
    }

  /* Open ALP file */

  alpfd = open(gps->assist->alp_file, O_RDWR);
  if (alpfd < 0)
    {
      int error = get_errno();

      dbg("ALP file '%s' open failed: %d.\n", gps->assist->alp_file, error);
      goto errout;
    }

  /* Seek to requested offset */

  status = lseek(alpfd, data_offset, SEEK_SET);
  if (status < 0)
    {
      int error = get_errno();

      dbg("Failed to seek ALP file to offset %d: %d.\n", data_offset,
          error);

      goto errout;
    }

  if (resp)
    {
      /* Read data from AlmanacPlus file */

      data_read = read(alpfd, &resp->payload[UBX_AID_ALPSRV_LEN], data_size);
      if (data_read < 0)
        {
          int error = get_errno();

          dbg("ALP file read failed (offset:%d, size:%d): %d.\n", data_offset,
              data_size, error);

          goto errout;
        }

      /* Set read data size */

      UBX_SET_U2(resp, 8, data_read);

      /* Send response */

      status = ubx_msg_send(gps, gps->fd, resp);
    }
  else
    {
      uint16_t file_id = UBX_GET_U2(msg, 6);

      /* Update data in AlmanacPlus file */

      if (file_id == gps->assist->alp_file_id)
        {
          status = write(alpfd, &msg->payload[8], data_size);
          if (status != data_size)
          {
            status = ERROR;
            dbg("ALP write failed: %d\n", get_errno());
          }
          else
          {
            status = OK;
          }
        }
    }

errout:

  if (resp)
    UBX_MSG_FREE(resp);

  if (alpfd >= 0)
    close(alpfd);

  pthread_mutex_unlock(&g_aid_mutex);

  return status;
}
Exemplo n.º 29
0
static int thread_create(FAR const char *name, uint8_t ttype, int priority,
                         int stack_size, main_t entry, FAR char * const argv[])
{
  FAR struct task_tcb_s *tcb;
  pid_t pid;
  int errcode;
  int ret;

  /* Allocate a TCB for the new task. */

  tcb = (FAR struct task_tcb_s *)kmm_zalloc(sizeof(struct task_tcb_s));
  if (!tcb)
    {
      sdbg("ERROR: Failed to allocate TCB\n");
      errcode = ENOMEM;
      goto errout;
    }

  /* Allocate a new task group with privileges appropriate for the parent
   * thread type.
   */

#ifdef HAVE_TASK_GROUP
  ret = group_allocate(tcb, ttype);
  if (ret < 0)
    {
      errcode = -ret;
      goto errout_with_tcb;
    }
#endif

  /* Associate file descriptors with the new task */

#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
  ret = group_setuptaskfiles(tcb);
  if (ret < OK)
    {
      errcode = -ret;
      goto errout_with_tcb;
    }
#endif

  /* Allocate the stack for the TCB */

  ret = up_create_stack((FAR struct tcb_s *)tcb, stack_size, ttype);
  if (ret < OK)
    {
      errcode = -ret;
      goto errout_with_tcb;
    }

  /* Initialize the task control block */

  ret = task_schedsetup(tcb, priority, task_start, entry, ttype);
  if (ret < OK)
    {
      errcode = EBUSY; /* No available PID */
      goto errout_with_tcb;
    }

  /* Setup to pass parameters to the new task */

  (void)task_argsetup(tcb, name, argv);

  /* Now we have enough in place that we can join the group */

#ifdef HAVE_TASK_GROUP
  ret = group_initialize(tcb);
  if (ret < 0)
    {
      errcode = -ret;
      goto errout_with_tcb;
    }
#endif

  /* Get the assigned pid before we start the task */

  pid = (int)tcb->cmn.pid;

  /* Activate the task */

  ret = task_activate((FAR struct tcb_s *)tcb);
  if (ret < OK)
    {
      errcode = get_errno();

      /* The TCB was added to the active task list by task_schedsetup() */

      dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
      goto errout_with_tcb;
    }

  return pid;

errout_with_tcb:
  sched_releasetcb((FAR struct tcb_s *)tcb, ttype);

errout:
  set_errno(errcode);
  return ERROR;
}
Exemplo n.º 30
0
ssize_t writev(int fildes, FAR const struct iovec *iov, int iovcnt)
{
  ssize_t ntotal;
  ssize_t nwritten;
  size_t remaining;
  FAR uint8_t *buffer;
  off_t pos;
  int i;

  /* Get the current file position in case we have to reset it */

  pos = lseek(fildes, 0, SEEK_CUR);
  if (pos == (off_t)-1)
    {
      return ERROR;
    }

  /* Process each entry in the struct iovec array */

  for (i = 0, ntotal = 0; i < iovcnt; i++)
    {
      /* Ignore zero-length writes */

      if (iov[i].iov_len > 0)
        {
          buffer    = iov[i].iov_base;
          remaining = iov[i].iov_len;

          /* Write repeatedly as necessary to write the entire buffer */

          do
            {
              /* NOTE:  write() is a cancellation point */

              nwritten = write(fildes, buffer, remaining);

              /* Check for a write error */

              if (nwritten < 0)
                {
                  /* Save the errno value */

                  int save = get_errno();

                  /* Restore the file position */

                  (void)lseek(fildes, pos, SEEK_SET);

                  /* Restore the errno value */

                  set_errno(save);
                  return ERROR;
                }

              /* Update pointers and counts in order to handle partial
               * buffer writes.
               */

              buffer    += nwritten;
              remaining -= nwritten;
              ntotal    += nwritten;
            }
          while (remaining > 0);
        }
    }

  return ntotal;
}