Exemplo n.º 1
0
int dup2(int sockfd1, int sockfd2)
#endif
{
  FAR struct socket *psock1;
  FAR struct socket *psock2;
  int err;
  int ret;

  /* Lock the scheduler throughout the following */

  sched_lock();

  /* Get the socket structures underly both descriptors */

  psock1 = sockfd_socket(sockfd1);
  psock2 = sockfd_socket(sockfd2);

  /* Verify that the sockfd1 and sockfd2 both refer to valid socket
   * descriptors and that sockfd2 corresponds to allocated socket
   */

  if (!psock1 || !psock2 || psock1->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* If sockfd2 also valid, allocated socket, then we will have to
   * close it!
   */

  if (psock2->s_crefs > 0)
    {
      net_close(sockfd2);
    }

  /* Duplicate the socket state */

  ret = net_clone(psock1, psock2);
  if (ret < 0)
    {
      err = -ret;
      goto errout;
    }

  sched_unlock();
  return OK;

errout:
  sched_unlock();
  errno = err;
  return ERROR;
}
Exemplo n.º 2
0
static inline void sched_dupsockets(FAR _TCB *tcb)
{
  /* The parent task is the one at the head of the ready-to-run list */

  FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
  FAR struct socket *parent;
  FAR struct socket *child;
  int i;

 /* Duplicate the socket descriptors of all sockets opened by the parent
  * task.
  */

  if (rtcb->sockets)
    {
      /* Get pointers to the parent and child task socket lists */

      parent = rtcb->sockets->sl_sockets;
      child  = tcb->sockets->sl_sockets;

      /* Check each socket in the parent socket list */

      for (i = 0; i < CONFIG_NSOCKET_DESCRIPTORS; i++)
        {
          /* Check if this parent socket is allocated.  We can tell if the
           * socket is allocated because it will have a positive, non-zero
           * reference count.
           */

          if (parent[i].s_crefs > 0)
            {
              /* Yes... duplicate it for the child */

              (void)net_clone(&parent[i], &child[i]);
            }
        }
    }
}
Exemplo n.º 3
0
FAR char *telnetd_driver(int sd, FAR struct telnetd_s *daemon)
{
  FAR struct telnetd_dev_s *priv;
  FAR struct socket *psock;
  FAR char *devpath = NULL;
  int ret;

  /* Allocate instance data for this driver */

  priv = (FAR struct telnetd_dev_s*)malloc(sizeof(struct telnetd_dev_s));
  if (!priv)
    {
      nlldbg("Failed to allocate the driver data structure\n");
      return NULL;
    }

  /* Initialize the allocated driver instance */

  sem_init(&priv->td_exclsem, 0, 1);

  priv->td_state   = STATE_NORMAL;
  priv->td_crefs   = 0;
  priv->td_pending = 0;
  priv->td_offset  = 0;

  /* Clone the internal socket structure.  We do this so that it will be
   * independent of threads and of socket descriptors (the original socket
   * instance resided in the daemon's socket array).
   */

  psock = sockfd_socket(sd);
  if (!psock)
    {
      nlldbg("Failed to convert sd=%d to a socket structure\n", sd);
      goto errout_with_dev;
    }

  ret = net_clone(psock, &priv->td_psock);
  if (ret < 0)
    {
      nlldbg("net_clone failed: %d\n", ret);
      goto errout_with_dev;
    }

  /* And close the original */

  psock_close(psock);

  /* Allocation a unique minor device number of the telnet drvier */

  do
    {
      ret = sem_wait(&g_telnetdcommon.exclsem);
      if (ret < 0 && errno != -EINTR)
        {
          goto errout_with_dev;
        }
    }
  while (ret < 0);

  priv->td_minor = g_telnetdcommon.minor;
  g_telnetdcommon.minor++;
  sem_post(&g_telnetdcommon.exclsem);

  /* Create a path and name for the driver. */

  ret = asprintf(&devpath, TELNETD_DEVFMT, priv->td_minor);
  if (ret < 0)
    {
      nlldbg("Failed to allocate the driver path\n");
      goto errout_with_dev;
    }

  /* Register the driver */

  ret = register_driver(devpath, &g_telnetdfops, 0666, priv);
  if (ret < 0)
    {
      nlldbg("Failed to register the driver %s: %d\n", devpath, ret);
      goto errout_with_devpath;
    }

  /* Return the path to the new telnet driver */

  return devpath;

errout_with_devpath:
  free(devpath);
errout_with_dev:
  free(priv);
  return NULL;
}