Example #1
0
FAR const char *inode_basename(FAR const char *name)
{
  FAR const char *basename = NULL;

  for (;;)
    {
      /* Get the name for the next path segment */

      name = inode_nextname(name);

      /* When the final segment is terminated by the NUL character, then
       * previous name that we saved is the basename.
       */

      if (*name == '\0')
        {
          return basename;
        }
    }

  /* We won't get here */

  return NULL;
}
Example #2
0
FAR struct inode *inode_search(const char **path,
                               FAR struct inode **peer,
                               FAR struct inode **parent,
                               const char **relpath)
{
  const char       *name  = *path + 1; /* Skip over leading '/' */
  FAR struct inode *node  = root_inode;
  FAR struct inode *left  = NULL;
  FAR struct inode *above = NULL;

  while (node)
    {
      int result = _inode_compare(name, node);

      /* Case 1:  The name is less than the name of the node.
       * Since the names are ordered, these means that there
       * is no peer node with this name and that there can be
       * no match in the fileystem.
       */

      if (result < 0)
        {
          node = NULL;
          break;
        }

      /* Case 2: the name is greater than the name of the node.
       * In this case, the name may still be in the list to the
       * "right"
       */

      else if (result > 0)
        {
          left = node;
          node = node->i_peer;
        }

      /* The names match */

      else
        {
          /* Now there are three more possibilities:
           *   (1) This is the node that we are looking for or,
           *   (2) The node we are looking for is "below" this one.
           *   (3) This node is a mountpoint and will absorb all request
           *       below this one
           */

          name = inode_nextname(name);
          if (!*name || INODE_IS_MOUNTPT(node))
            {
              /* Either (1) we are at the end of the path, so this must be the
               * node we are looking for or else (2) this node is a mountpoint
               * and will handle the remaining part of the pathname
               */

              if (relpath)
                {
                  *relpath = name;
                }
              break;
            }
          else
            {
              /* More to go, keep looking at the next level "down" */

              above = node;
              left  = NULL;
              node = node->i_child;
            }
        }
    }

  /* node is null.  This can happen in one of four cases:
   * With node = NULL
   *   (1) We went left past the final peer:  The new node
   *       name is larger than any existing node name at
   *       that level.
   *   (2) We broke out in the middle of the list of peers
   *       because the name was not found in the ordered
   *       list.
   *   (3) We went down past the final parent:  The new node
   *       name is "deeper" than anything that we currently
   *       have in the tree.
   * with node != NULL
   *   (4) When the node matching the full path is found
   */

  if (peer)
    {
      *peer = left;
    }

  if (parent)
    {
      *parent = above;
    }

  *path = name;
  return node;
}
Example #3
0
int inode_reserve(FAR const char *path, FAR struct inode **inode)
{
  const char       *name = path;
  FAR struct inode *left;
  FAR struct inode *parent;

  /* Assume failure */

  DEBUGASSERT(path && inode);
  *inode = NULL;

  /* Handle paths that are interpreted as the root directory */

  if (!*path || path[0] != '/')
    {
      return -EINVAL;
    }

  /* Find the location to insert the new subtree */

  if (inode_search(&name, &left, &parent, (FAR const char **)NULL) != NULL)
    {
      /* It is an error if the node already exists in the tree */

      return -EEXIST;
    }

  /* Now we now where to insert the subtree */

  for (;;)
    {
      FAR struct inode *node;

      /* Create a new node -- we need to know if this is the
       * the leaf node or some intermediary.  We can find this
       * by looking at the next name.
       */

      FAR const char *next_name = inode_nextname(name);
      if (*next_name)
        {
          /* Insert an operationless node */

          node = inode_alloc(name);
          if (node)
            {
              inode_insert(node, left, parent);

              /* Set up for the next time through the loop */

              name   = next_name;
              left   = NULL;
              parent = node;
              continue;
            }
        }
      else
        {
          node = inode_alloc(name);
          if (node)
            {
              inode_insert(node, left, parent);
              *inode = node;
              return OK;
            }
        }

      /* We get here on failures to allocate node memory */

      return -ENOMEM;
    }
}