コード例 #1
0
ファイル: imfs_fchmod.c プロジェクト: zhongweiy/rtems
int IMFS_fchmod(
    const rtems_filesystem_location_info_t *loc,
    mode_t mode
)
{
    IMFS_jnode_t  *jnode;
#if defined(RTEMS_POSIX_API)
    uid_t          st_uid;
#endif

    jnode = loc->node_access;

    /*
     *  Verify I am the owner of the node or the super user.
     */
#if defined(RTEMS_POSIX_API)
    st_uid = geteuid();

    if ( ( st_uid != jnode->st_uid ) && ( st_uid != 0 ) )
        rtems_set_errno_and_return_minus_one( EPERM );
#endif

    /*
     * Change only the RWX permissions on the jnode to mode.
     */

    jnode->st_mode &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);
    jnode->st_mode |= mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX);

    IMFS_update_ctime( jnode );

    return 0;
}
コード例 #2
0
ファイル: imfs_mknod.c プロジェクト: AndroidMarv/rtems
int IMFS_mknod(
  const rtems_filesystem_location_info_t *parentloc,
  const char *name,
  size_t namelen,
  mode_t mode,
  dev_t dev
)
{
  int rv = 0;
  IMFS_jnode_types_t type;
  IMFS_types_union info;
  IMFS_jnode_t *new_node;

  get_type_and_info_by_mode_and_dev( mode, dev, &type, &info );

  new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &info );
  if ( new_node != NULL ) {
    IMFS_jnode_t *parent = parentloc->node_access;

    IMFS_update_ctime( parent );
    IMFS_update_mtime( parent );
  } else {
    rv = -1;
  }

  return rv;
}
コード例 #3
0
ファイル: imfs_link.c プロジェクト: AoLaD/rtems
static IMFS_jnode_t *IMFS_node_remove_hard_link(
  IMFS_jnode_t *node
)
{
  IMFS_link_t *hard_link = (IMFS_link_t *) node;
  IMFS_jnode_t *target = hard_link->link_node;

  _Assert( target != NULL );

  if ( target->st_nlink == 1 ) {
    target = (*target->control->node_remove)( target );
    if ( target == NULL ) {
      node = NULL;
    }
  } else {
    --target->st_nlink;
    IMFS_update_ctime( target );
  }

  if ( target != NULL ) {
    --target->reference_count;

    if ( target->reference_count == 0 ) {
      IMFS_node_destroy( target );
    }
  }

  return node;
}
コード例 #4
0
int IMFS_chown(
  rtems_filesystem_location_info_t  *pathloc,       /* IN */
  uid_t                              owner,         /* IN */
  gid_t                              group          /* IN */
)
{
  IMFS_jnode_t  *jnode;
#if defined(RTEMS_POSIX_API)
  uid_t          st_uid;
#endif

  jnode = (IMFS_jnode_t *) pathloc->node_access;

  /*
   *  Verify I am the owner of the node or the super user.
   */

#if defined(RTEMS_POSIX_API)
  st_uid = geteuid();

  if ( ( st_uid != jnode->st_uid ) && ( st_uid != 0 ) )
    rtems_set_errno_and_return_minus_one( EPERM );
#endif

  jnode->st_uid = owner;
  jnode->st_gid = group;

  IMFS_update_ctime( jnode );

  return 0;
}
コード例 #5
0
ファイル: memfile.c プロジェクト: epicsdeb/rtems
int memfile_rmnod(
  rtems_filesystem_location_info_t  *parent_pathloc,  /* IN */
  rtems_filesystem_location_info_t  *pathloc          /* IN */
)
{
  IMFS_jnode_t *the_jnode;

  the_jnode = (IMFS_jnode_t *) pathloc->node_access;

  /*
   * Take the node out of the parent's chain that contains this node
   */

  if ( the_jnode->Parent != NULL ) {
    rtems_chain_extract( (rtems_chain_node *) the_jnode );
    the_jnode->Parent = NULL;
  }

  /*
   * Decrement the link counter and see if we can free the space.
   */

  the_jnode->st_nlink--;
  IMFS_update_ctime( the_jnode );

  return memfile_check_rmnod( the_jnode );
}
コード例 #6
0
ファイル: imfs_unlink.c プロジェクト: epicsdeb/rtems
int IMFS_unlink(
  rtems_filesystem_location_info_t  *parentloc, /* IN */
  rtems_filesystem_location_info_t  *loc        /* IN */
)
{
  IMFS_jnode_t                      *node;
  rtems_filesystem_location_info_t   the_link;
  int                                result = 0;

  node = loc->node_access;

  /*
   * Decrement the link counter of node pointed to and free the
   * space.
   */

  /*
   * If this is the last last pointer to the node
   * free the node.
   */

  if ( node->type == IMFS_HARD_LINK ) {

    if ( !node->info.hard_link.link_node )
      rtems_set_errno_and_return_minus_one( EINVAL );

    the_link = *loc;
    the_link.node_access = node->info.hard_link.link_node;
    IMFS_Set_handlers( &the_link );

    /*
     *  If removing the last hard link to a node, then we need
     *  to remove the node that is a link and the node itself.
     */

    if ( node->info.hard_link.link_node->st_nlink == 1)
    {
        result = (*the_link.handlers->rmnod_h)( parentloc, &the_link );
        if ( result != 0 )
            return -1;
    }
    else
    {
        node->info.hard_link.link_node->st_nlink --;
        IMFS_update_ctime( node->info.hard_link.link_node );
    }
  }

  /*
   *  Now actually free the node we were asked to free.
   */

  result = (*loc->handlers->rmnod_h)( parentloc, loc );

  return result;
}
コード例 #7
0
ファイル: imfs_rmnod.c プロジェクト: rtemss/rtems
void IMFS_create_orphan( IMFS_jnode_t *jnode )
{
  if ( jnode->Parent != NULL ) {
    rtems_chain_extract( &jnode->Node );
    jnode->Parent = NULL;
  }

  --jnode->st_nlink;

  IMFS_update_ctime( jnode );
}
コード例 #8
0
ファイル: memfile.c プロジェクト: aniwang2013/leon-rtems
/*
 *  IMFS_memfile_extend
 *
 *  This routine insures that the in-memory file is of the length
 *  specified.  If necessary, it will allocate memory blocks to
 *  extend the file.
 */
MEMFILE_STATIC int IMFS_memfile_extend(
   IMFS_jnode_t  *the_jnode,
   off_t          new_length
)
{
  unsigned int   block;
  unsigned int   new_blocks;
  unsigned int   old_blocks;

  /*
   *  Perform internal consistency checks
   */
  IMFS_assert( the_jnode );
    IMFS_assert( IMFS_type( the_jnode ) == IMFS_MEMORY_FILE );

  /*
   *  Verify new file size is supported
   */
  if ( new_length >= IMFS_MEMFILE_MAXIMUM_SIZE )
    rtems_set_errno_and_return_minus_one( EINVAL );

  /*
   *  Verify new file size is actually larger than current size
   */
  if ( new_length <= the_jnode->info.file.size )
    return 0;

  /*
   *  Calculate the number of range of blocks to allocate
   */
  new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK;
  old_blocks = the_jnode->info.file.size / IMFS_MEMFILE_BYTES_PER_BLOCK;

  /*
   *  Now allocate each of those blocks.
   */
  for ( block=old_blocks ; block<=new_blocks ; block++ ) {
    if ( IMFS_memfile_addblock( the_jnode, block ) ) {
       for ( ; block>=old_blocks ; block-- ) {
         IMFS_memfile_remove_block( the_jnode, block );
       }
       rtems_set_errno_and_return_minus_one( ENOSPC );
    }
  }

  /*
   *  Set the new length of the file.
   */
  the_jnode->info.file.size = new_length;

  IMFS_update_ctime(the_jnode);
  IMFS_update_mtime(the_jnode);
  return 0;
}
コード例 #9
0
ファイル: imfs_mknod.c プロジェクト: rtemss/rtems
int IMFS_mknod(
  const char                        *token,      /* IN */
  mode_t                             mode,       /* IN */
  dev_t                              dev,        /* IN */
  rtems_filesystem_location_info_t  *pathloc     /* IN/OUT */
)
{
  IMFS_token_types   type = 0;
  IMFS_jnode_t      *new_node;
  int                result;
  char               new_name[ IMFS_NAME_MAX + 1 ];
  IMFS_types_union   info;

  IMFS_get_token( token, strlen( token ), new_name, &result );

  /*
   *  Figure out what type of IMFS node this is.
   */
  if ( S_ISDIR(mode) )
    type = IMFS_DIRECTORY;
  else if ( S_ISREG(mode) )
    type = IMFS_MEMORY_FILE;
  else if ( S_ISBLK(mode) || S_ISCHR(mode) ) {
    type = IMFS_DEVICE;
    rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor );
  } else if (S_ISFIFO(mode))
    type = IMFS_FIFO;
  else 
    IMFS_assert( 0 );

  /*
   *  Allocate and fill in an IMFS jnode
   *
   *  NOTE: Coverity Id 21 reports this as a leak.
   *        While technically not a leak, it indicated that IMFS_create_node
   *        was ONLY passed a NULL when we created the root node.  We
   *        added a new IMFS_create_root_node() so this path no longer
   *        existed.  The result was simpler code which should not have
   *        this path. 
   */
  new_node = IMFS_create_node( pathloc, type, new_name, mode, &info );
  if ( !new_node )
    rtems_set_errno_and_return_minus_one( ENOMEM );

  IMFS_update_ctime(new_node->Parent);
  IMFS_update_mtime(new_node->Parent);
  return 0;
}
コード例 #10
0
ファイル: imfs_chown.c プロジェクト: gedare/rtems
int IMFS_chown(
  const rtems_filesystem_location_info_t *loc,
  uid_t owner,
  gid_t group
)
{
  IMFS_jnode_t *jnode;

  jnode = (IMFS_jnode_t *) loc->node_access;

  jnode->st_uid = owner;
  jnode->st_gid = group;

  IMFS_update_ctime( jnode );

  return 0;
}
コード例 #11
0
ファイル: imfs_handlers_link.c プロジェクト: cloud-hot/rtems
static IMFS_jnode_t *IMFS_node_remove_hard_link(
  IMFS_jnode_t *node
)
{
  IMFS_jnode_t *target = node->info.hard_link.link_node;

  if ( target->st_nlink == 1) {
    target = (*target->control->node_remove)( target );
    if ( target == NULL ) {
      node = NULL;
    }
  } else {
    --target->st_nlink;
    IMFS_update_ctime( target );
  }

  return node;
}
コード例 #12
0
ファイル: imfs_link.c プロジェクト: AndroidMarv/rtems
int IMFS_link(
  const rtems_filesystem_location_info_t *parentloc,
  const rtems_filesystem_location_info_t *targetloc,
  const char *name,
  size_t namelen
)
{
  IMFS_types_union   info;
  IMFS_jnode_t      *new_node;
  IMFS_jnode_t      *target;

  target = targetloc->node_access;
  info.hard_link.link_node = target;

  /*
   *  Verify this node can be linked to.
   */
  if ( target->st_nlink >= LINK_MAX )
    rtems_set_errno_and_return_minus_one( EMLINK );

  /*
   *  Create a new link node.
   */
  new_node = IMFS_create_node(
    parentloc,
    IMFS_HARD_LINK,
    name,
    namelen,
    ( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
    &info
  );

  if ( !new_node )
    rtems_set_errno_and_return_minus_one( ENOMEM );

  /*
   * Increment the link count of the node being pointed to.
   */
  target->reference_count++;
  target->st_nlink++;
  IMFS_update_ctime( target );

  return 0;
}
コード例 #13
0
ファイル: imfs_rename.c プロジェクト: atixing/rtems
int IMFS_rename(
  const rtems_filesystem_location_info_t *oldparentloc,
  const rtems_filesystem_location_info_t *oldloc,
  const rtems_filesystem_location_info_t *newparentloc,
  const char *name,
  size_t namelen
)
{
  int rv = 0;
  IMFS_jnode_t *node = oldloc->node_access;
  IMFS_jnode_t *new_parent = newparentloc->node_access;

  /*
   * FIXME: Due to insufficient checks we can create inaccessible nodes with
   * this operation.
   */

  if ( node->Parent != NULL ) {
    if ( namelen < IMFS_NAME_MAX ) {
      memcpy( node->name, name, namelen );
      node->name [namelen] = '\0';

      IMFS_remove_from_directory( node );
      IMFS_add_to_directory( new_parent, node );
      IMFS_update_ctime( node );
    } else {
      errno = ENAMETOOLONG;
      rv = -1;
    }
  } else {
    errno = EINVAL;
    rv = -1;
  }

  return rv;
}
コード例 #14
0
ファイル: imfs_directory.c プロジェクト: epicsdeb/rtems
int imfs_dir_rmnod(
  rtems_filesystem_location_info_t  *parent_pathloc, /* IN */
  rtems_filesystem_location_info_t  *pathloc         /* IN */
)
{
  IMFS_jnode_t *the_jnode;

  the_jnode = (IMFS_jnode_t *) pathloc->node_access;

  /*
   * You cannot remove a node that still has children
   */

  if ( ! rtems_chain_is_empty( &the_jnode->info.directory.Entries ) )
     rtems_set_errno_and_return_minus_one( ENOTEMPTY );

  /*
   * You cannot remove the file system root node.
   */

  if ( pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access )
     rtems_set_errno_and_return_minus_one( EBUSY );

  /*
   * You cannot remove a mountpoint.
   */

   if ( the_jnode->info.directory.mt_fs != NULL )
     rtems_set_errno_and_return_minus_one( EBUSY );

  /*
   * Take the node out of the parent's chain that contains this node
   */

  if ( the_jnode->Parent != NULL ) {
    rtems_chain_extract( (rtems_chain_node *) the_jnode );
    the_jnode->Parent = NULL;
  }

  /*
   * Decrement the link counter and see if we can free the space.
   */

  the_jnode->st_nlink--;
  IMFS_update_ctime( the_jnode );

  /*
   * The file cannot be open and the link must be less than 1 to free.
   */

  if ( !rtems_libio_is_file_open( the_jnode ) && (the_jnode->st_nlink < 1) ) {

    /*
     * Is the rtems_filesystem_current is this node?
     */

    if ( rtems_filesystem_current.node_access == pathloc->node_access )
       rtems_filesystem_current.node_access = NULL;

    /*
     * Free memory associated with a memory file.
     */

    free( the_jnode );
  }

  return 0;

}
コード例 #15
0
int IMFS_make_generic_node(
  const char *path,
  mode_t mode,
  const IMFS_node_control *node_control,
  void *context
)
{
  int rv = 0;

  mode &= ~rtems_filesystem_umask;

  switch (mode & S_IFMT) {
    case S_IFBLK:
    case S_IFCHR:
    case S_IFIFO:
    case S_IFREG:
      break;
    default:
      errno = EINVAL;
      rv = -1;
      break;
  }
  
  if ( rv == 0 ) {
    if ( node_control->imfs_type == IMFS_GENERIC ) {
      rtems_filesystem_eval_path_context_t ctx;
      int eval_flags = RTEMS_FS_FOLLOW_LINK
        | RTEMS_FS_MAKE
        | RTEMS_FS_EXCLUSIVE;
      const rtems_filesystem_location_info_t *currentloc =
        rtems_filesystem_eval_path_start( &ctx, path, eval_flags );

      if ( IMFS_is_imfs_instance( currentloc ) ) {
        IMFS_types_union info;
        IMFS_jnode_t *new_node;

        info.generic.context = context;
        new_node = IMFS_create_node_with_control(
          currentloc,
          node_control,
          rtems_filesystem_eval_path_get_token( &ctx ),
          rtems_filesystem_eval_path_get_tokenlen( &ctx ),
          mode,
          &info
        );

        if ( new_node != NULL ) {
          IMFS_jnode_t *parent = currentloc->node_access;

          IMFS_update_ctime( parent );
          IMFS_update_mtime( parent );
        } else {
          rv = -1;
        }
      } else {
        rtems_filesystem_eval_path_error( &ctx, ENOTSUP );
        rv = -1;
      }

      rtems_filesystem_eval_path_cleanup( &ctx );
    } else {
      errno = EINVAL;
      rv = -1;
    }
  }

  return rv;
}