static rtems_filesystem_location_info_t * eval_path_start( rtems_filesystem_eval_path_context_t *ctx, const char *path, size_t pathlen, int eval_flags, rtems_filesystem_global_location_t *const *global_root_ptr, rtems_filesystem_global_location_t *const *global_current_ptr ) { memset(ctx, 0, sizeof(*ctx)); ctx->path = path; ctx->pathlen = pathlen; ctx->flags = eval_flags; set_startloc(ctx, global_root_ptr, global_current_ptr); rtems_filesystem_instance_lock(&ctx->startloc->location); rtems_filesystem_location_clone( &ctx->currentloc, &ctx->startloc->location ); rtems_filesystem_eval_path_continue(ctx); return &ctx->currentloc; }
static int duplicate_iop( rtems_libio_t *iop ) { int rv = 0; rtems_libio_t *diop = rtems_libio_allocate(); if (diop != NULL) { int oflag = rtems_libio_to_fcntl_flags( iop->flags ); oflag &= ~O_CREAT; diop->flags |= rtems_libio_fcntl_flags( oflag ); rtems_filesystem_instance_lock( &iop->pathinfo ); rtems_filesystem_location_clone( &diop->pathinfo, &iop->pathinfo ); rtems_filesystem_instance_unlock( &iop->pathinfo ); /* * XXX: We call the open handler here to have a proper open and close pair. * * FIXME: What to do with the path? */ rv = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 ); if ( rv == 0 ) { rv = rtems_libio_iop_to_descriptor( diop ); } else { rtems_libio_free( diop ); } } else { rv = -1; } return rv; }
rtems_filesystem_node_types_t rtems_filesystem_node_type( const rtems_filesystem_location_info_t *loc ) { rtems_filesystem_node_types_t type; rtems_filesystem_instance_lock(loc); type = (*loc->mt_entry->ops->node_type_h)(loc); rtems_filesystem_instance_unlock(loc); return type; }
void rtems_filesystem_eval_path_restart( rtems_filesystem_eval_path_context_t *ctx, rtems_filesystem_global_location_t **newstartloc_ptr ) { free_location(&ctx->currentloc); rtems_filesystem_instance_unlock(&ctx->startloc->location); rtems_filesystem_global_location_assign( &ctx->startloc, rtems_filesystem_global_location_obtain(newstartloc_ptr) ); rtems_filesystem_instance_lock(&ctx->startloc->location); rtems_filesystem_location_clone(&ctx->currentloc, &ctx->startloc->location); }
/** * POSIX 1003.1b 5.6.5 - Change Owner and Group of a File */ int fchown( int fd, uid_t owner, gid_t group ) { int rv; rtems_libio_t *iop; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open(iop); rtems_filesystem_instance_lock( &iop->pathinfo ); rv = rtems_filesystem_chown( &iop->pathinfo, owner, group ); rtems_filesystem_instance_unlock( &iop->pathinfo ); return rv; }
int fchdir( int fd ) { int rv = 0; rtems_libio_t *iop; struct stat st; rtems_filesystem_location_info_t loc; st.st_mode = 0; st.st_uid = 0; st.st_gid = 0; rtems_libio_check_fd( fd ); iop = rtems_libio_iop( fd ); rtems_libio_check_is_open( iop ); rtems_filesystem_instance_lock( &iop->pathinfo ); rv = (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, &st ); if ( rv == 0 ) { bool access_ok = rtems_filesystem_check_access( RTEMS_FS_PERMS_EXEC, st.st_mode, st.st_uid, st.st_gid ); if ( access_ok ) { rtems_filesystem_location_clone( &loc, &iop->pathinfo ); } else { errno = EACCES; rv = -1; } } rtems_filesystem_instance_unlock( &iop->pathinfo ); if ( rv == 0 ) { rv = rtems_filesystem_chdir( &loc ); } return rv; }
static int duplicate2_iop( rtems_libio_t *iop, int fd2 ) { rtems_libio_t *iop2; int rv = 0; rtems_libio_check_fd( fd2 ); iop2 = rtems_libio_iop( fd2 ); if (iop != iop2) { int oflag; if ((iop2->flags & LIBIO_FLAGS_OPEN) != 0) { rv = (*iop2->pathinfo.handlers->close_h)( iop2 ); } if (rv == 0) { oflag = rtems_libio_to_fcntl_flags( iop->flags ); oflag &= ~O_CREAT; iop2->flags |= rtems_libio_fcntl_flags( oflag ); rtems_filesystem_instance_lock( &iop->pathinfo ); rtems_filesystem_location_clone( &iop2->pathinfo, &iop->pathinfo ); rtems_filesystem_instance_unlock( &iop->pathinfo ); /* * XXX: We call the open handler here to have a proper open and close * pair. * * FIXME: What to do with the path? */ rv = (*iop2->pathinfo.handlers->open_h)( iop2, NULL, oflag, 0 ); if ( rv == 0 ) { rv = fd2; } } } return rv; }
static ssize_t IMFS_dir_read( rtems_libio_t *iop, void *buffer, size_t count ) { /* * Read up to element iop->offset in the directory chain of the * imfs_jnode_t struct for this file descriptor. */ const IMFS_directory_t *dir; const rtems_chain_node *node; const rtems_chain_control *entries; struct dirent *dir_ent; ssize_t bytes_transferred; off_t current_entry; off_t first_entry; off_t last_entry; rtems_filesystem_instance_lock( &iop->pathinfo ); dir = IMFS_iop_to_directory( iop ); entries = &dir->Entries; /* Move to the first of the desired directory entries */ bytes_transferred = 0; first_entry = iop->offset; /* protect against using sizes that are not exact multiples of the */ /* -dirent- size. These could result in unexpected results */ last_entry = first_entry + (count / sizeof( *dir_ent )) * sizeof( *dir_ent ); /* The directory was not empty so try to move to the desired entry in chain*/ for ( current_entry = 0, node = rtems_chain_immutable_first( entries ); current_entry < last_entry && !rtems_chain_is_tail( entries, node ); current_entry += sizeof( *dir_ent ), node = rtems_chain_immutable_next( node ) ) { if( current_entry >= first_entry ) { const IMFS_jnode_t *imfs_node = (const IMFS_jnode_t *) node; dir_ent = (struct dirent *) ((char *) buffer + bytes_transferred); /* Move the entry to the return buffer */ dir_ent->d_off = current_entry; dir_ent->d_reclen = sizeof( *dir_ent ); dir_ent->d_ino = IMFS_node_to_ino( imfs_node ); dir_ent->d_namlen = MIN( imfs_node->namelen, sizeof( dir_ent->d_name ) - 1 ); dir_ent->d_name[ dir_ent->d_namlen ] = '\0'; memcpy( dir_ent->d_name, imfs_node->name, dir_ent->d_namlen ); iop->offset += sizeof( *dir_ent ); bytes_transferred += (ssize_t) sizeof( *dir_ent ); } } rtems_filesystem_instance_unlock( &iop->pathinfo ); return bytes_transferred; }