Exemple #1
0
int inode_stat(FAR struct inode *inode, FAR struct stat *buf)
{
	DEBUGASSERT(inode != NULL && buf != NULL);

	memset(buf, 0, sizeof(*buf));

	if (INODE_IS_SPECIAL(inode)) {
#if defined(CONFIG_FS_NAMED_SEMAPHORES)
		if (INODE_IS_NAMEDSEM(inode)) {
			buf->st_mode = S_IFSEM;
		} else
#endif
#if !defined(CONFIG_DISABLE_MQUEUE)
		if (INODE_IS_MQUEUE(inode)) {
			buf->st_mode = S_IFMQ;
		} else
#endif
		{
		}
	} else if (inode->u.i_ops != NULL) {
		/* Determine read/write privileges based on the existence of read
		 * and write methods.
		 */
		if (inode->u.i_ops->read) {
			buf->st_mode = S_IROTH | S_IRGRP | S_IRUSR;
		}
		if (inode->u.i_ops->write) {
			buf->st_mode |= S_IWOTH | S_IWGRP | S_IWUSR;
		}
		/* Determine the type of the inode */
		if (INODE_IS_MOUNTPT(inode)) {
			buf->st_mode |= S_IFDIR;
		} else if (INODE_IS_BLOCK(inode)) {
			/* What is if also has child inodes? */
			buf->st_mode |= S_IFBLK;
		} else /* if (INODE_IS_DRIVER(inode)) */ {
			/* What is it if it also has child inodes? */
			buf->st_mode |= S_IFCHR;
		}
	} else {
		/* If it has no operations, then it must just be a intermediate
		 * node in the inode tree. It is something like a directory.
		 * We'll say that all pseudo-directories are read-able but not
		 * write-able.
		 */
		buf->st_mode |= S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
	}

	return OK;
}
Exemple #2
0
int unlink(FAR const char *pathname)
{
  FAR struct inode *inode;
  const char       *relpath = NULL;
  int               errcode;
  int               ret;

  /* Get an inode for this file */

  inode = inode_find(pathname, &relpath);
  if (!inode)
    {
      /* There is no inode that includes in this path */

      errcode = ENOENT;
      goto errout;
    }

#ifndef CONFIG_DISABLE_MOUNTPOINT
  /* Check if the inode is a valid mountpoint. */

  if (INODE_IS_MOUNTPT(inode) && inode->u.i_mops)
    {
      /* Perform the unlink operation using the relative path at the
       * mountpoint.
       */

      if (inode->u.i_mops->unlink)
        {
          ret = inode->u.i_mops->unlink(inode, relpath);
          if (ret < 0)
            {
              errcode = -ret;
              goto errout_with_inode;
            }
        }
      else
        {
          errcode = ENOSYS;
          goto errout_with_inode;
        }
    }
  else
#endif

#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
  /* If this is a "dangling" pseudo-file node (i.e., it has operations) then rm
   * should remove the node.
   */

  if (!INODE_IS_SPECIAL(inode) && inode->u.i_ops)
    {
      /* If this is a pseudo-file node (i.e., it has no operations)
       * then rmdir should remove the node.
       */

      if (inode->u.i_ops)
        {
          inode_semtake();

          /* Refuse to unlink the inode if it has children.  I.e., if it is
           * functioning as a directory and the directory is not empty.
           */

          if (inode->i_child != NULL)
            {
              errcode = ENOTEMPTY;
              inode_semgive();
              goto errout_with_inode;
            }

          /* Remove the old inode.  Because we hold a reference count on the
           * inode, it will not be deleted now.  It will be deleted when all
           * of the references to to the inode have been released (perhaps
           * when inode_release() is called below).  inode_remove() will
           * return -EBUSY to indicate that the inode was not deleted now.
           */

          ret = inode_remove(pathname);
          inode_semgive();

          if (ret < 0 && ret != -EBUSY)
            {
              errcode = -ret;
              goto errout_with_inode;
            }
        }
      else
        {
          errcode = EISDIR;
          goto errout_with_inode;
        }
    }
  else
#endif
    {
      errcode = ENXIO;
      goto errout_with_inode;
    }

  /* Successfully unlinked */

  inode_release(inode);
  return OK;

 errout_with_inode:
  inode_release(inode);
 errout:
  set_errno(errcode);
  return ERROR;
}