⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nu_file.c

📁 nucleus 文件系统,内核和彩色图形系统,在小系统上非常好用
💻 C
📖 第 1 页 / 共 5 页
字号:

    ret_val = 0;

    if ( (pfile = pc_fd2file(fd, YES)) == NULL)
    {
        fs_user->p_errno = PEBADF;
        ret_val = -1;
    }
    else
    {
        driveno = pfile->pobj->pdrive->driveno;
        PC_DRIVE_ENTER(driveno, NO)  /* Register drive in use */
        ret_val = 0;
        fs_user->p_errno = 0;    
        if (pfile->flag & ( PO_RDWR | PO_WRONLY ) )
        {
            PC_INODE_ENTER(pfile->pobj->finode, YES)
            if (!_po_flush(pfile))
                ret_val = -1;
            PC_INODE_EXIT(pfile->pobj->finode)
        }
        /* Release the FD and its core */
        pc_freefile(fd);
        PC_DRIVE_EXIT(driveno)
    }
    /* Restore the kernel state */
    PC_FS_EXIT()
    return(ret_val);
}

/***************************************************************************
    PC_MV -  Rename a file.

 Description
    Renames the file in path (name) to newname. Fails if name is invalid,
    newname already exists or path not found. Does not test if name is a simple
    file. It is possible to rename volumes and directories. (This may change in 
    the multiuser version)

 Returns
    Returns YES if the file was renamed. Or no if the name not found.

***************************************************************************/

/* Rename a file */
BOOL NU_Rename(TEXT *name, TEXT *newname)							 /*__fn__*/
{
    DROBJ *pobj;
    DROBJ *parent_obj;
    TEXT mompath[EMAXPATH];
    TEXT filename[9];
    TEXT fileext[4];
    TEXT newfilename[9];
    TEXT newext[4];
    BOOL ret_val;   
    COUNT driveno;
    BOOL  parent_is_locked;
    PC_FS_ENTER()     /* Must be last line in declarations */
    CHECK_USER(BOOL, 0) /* Check if a valid user if multitasking */

    pobj = NULL;
    parent_obj = NULL;
    parent_is_locked = NO;
    ret_val = NO;

    if (!pc_parsedrive( &driveno, name ))
    {
        fs_user->p_errno = PENOENT;
        goto return_error;
    }   

    PC_DRIVE_ENTER(driveno, NO)        /* Register access to the drive */

    /* Get the new filename note: we will re-use mompath
       the new file name may not hav a path component */
    if (!pc_parsepath(mompath,newfilename,newext,newname) || mompath[0])
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    /* Get the path */
    if (!pc_parsepath(mompath,filename,fileext,name))
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    parent_obj = pc_fndnode(mompath);

    if (!parent_obj)
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    PC_INODE_ENTER(parent_obj->finode, YES)
    parent_is_locked = YES;

    /* Fail if the new file exists */
    pobj = pc_get_inode(NULL, parent_obj, (UTEXT*)newfilename, (UTEXT*)newext);
    if (pobj)
    {
        fs_user->p_errno = PEEXIST;
        goto errex;
    }
    /* Find the file and init the structure */
    pobj = pc_get_inode(NULL, parent_obj, (UTEXT*)filename, (UTEXT*)fileext);

    if (!pobj)
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    copybuff(filename, pobj->finode->fname, 8 );
    copybuff(fileext, pobj->finode->fext, 3 );
    copybuff(pobj->finode->fname , newfilename, 8 );
    copybuff(pobj->finode->fext , newext, 3 );
    ret_val = pc_update_inode(pobj);

    if (!ret_val)
    {
        copybuff(pobj->finode->fname , filename, 8 );
        copybuff(pobj->finode->fext ,  fileext, 3 );
        fs_user->p_errno = PENOSPC;
    }
errex:
    
    if (pobj)
        pc_freeobj(pobj);
    if (parent_obj)
    {
        if (parent_is_locked)
            PC_INODE_EXIT(parent_obj->finode)
        pc_freeobj(parent_obj);
    }
    PC_DRIVE_EXIT(driveno)

return_error:      /* Not only errors return through here. Everything does. */
    /* Restore the kernel state */
    PC_FS_EXIT()
    return(ret_val);
}

/****************************************************************************
    PC_UNLINK - Delete a file.

 Description
    Delete the file in name. Fail if not a simple file,if it is open,
    does not exist or is read only.

 Returns
    Returns YES if it successfully deleted the file.
    
    If NO is returned fs_user->p_errno will be set to one of these values

    PENOENT        - File not found or path to file not found
    PEACCES       - Attempt delete a directory or an open file
    PENOSPC        - Write failed

***************************************************************************/

/* Delete a file */
BOOL NU_Delete(TEXT *name)											 /*__fn__*/
{
    DROBJ *pobj;
    DROBJ *parent_obj;
    BOOL ret_val;
    TEXT  path[EMAXPATH];
    TEXT  filename[9];
    TEXT  fileext[4];
    COUNT driveno;
    BOOL  parent_is_locked;
    PC_FS_ENTER()     /* Must be last line in declarations */
    CHECK_USER(BOOL, 0) /* Check if a valid user if multitasking */

    ret_val     = NO;
    parent_obj  = NULL;
    pobj        = NULL;
    parent_is_locked = NO;

    if (!pc_parsedrive( &driveno, name ))
    {
        fs_user->p_errno = PENOENT;
        goto return_error;
    }   

    PC_DRIVE_ENTER(driveno, NO)        /* Register access to the drive */
    fs_user->p_errno = 0;

    /* Get out the filename and d:parent */
    if (!pc_parsepath(path,filename,fileext,name))
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    /* Find the parent and make sure it is a directory \ */
    parent_obj = pc_fndnode(path);
    if (!parent_obj || !pc_isadir(parent_obj) ||  pc_isavol(parent_obj))
    {
        fs_user->p_errno = PEACCES;
        goto errex;
    }
    PC_INODE_ENTER(parent_obj->finode, YES)
    parent_is_locked = YES;

    /* Find the file */
    pobj = pc_get_inode(NULL, parent_obj, (UTEXT*)filename, (UTEXT*)fileext);

    if (pobj)
    {
        /* Be sure it is not the root. Since the root is an abstraction 
           we can not delete it */
        if (pc_isroot(pobj))
        {
            fs_user->p_errno = PEACCES;
            ret_val = NO;
            goto errex;
        }
        /* Check access permissions */
        else if (pobj->finode->fattribute & ( ARDONLY | AVOLUME | ADIRENT) )
        {
            fs_user->p_errno = PEACCES;
            ret_val = NO;
            goto errex;
        }
        else if (pobj->finode->opencount > 1)
        {
            fs_user->p_errno = PEACCES;
            ret_val = NO;
            goto errex;
        }
        else
        {
            ret_val = pc_rmnode(pobj);
            if (!ret_val)
                fs_user->p_errno = PENOSPC;
        }
    }

errex:
    if (pobj)
        pc_freeobj(pobj);
    if (parent_obj)
    {
        if (parent_is_locked)
            PC_INODE_EXIT(parent_obj->finode)
        pc_freeobj(parent_obj);
    }
    PC_DRIVE_EXIT(driveno)

return_error:      /* Not only errors return through here. Everything does. */
    /* Restore the kernel state */
    PC_FS_EXIT()
    return(ret_val);
}

/****************************************************************************
    PC_RMDIR - Delete a directory.

Description

    Delete the directory specified in name. Fail if name is not a directory,
    is read only or contains more than the entries . and ..

 Returns
    Returns YES if the directory was successfully removed.

    If NO is returned fs_user->p_errno will be set to one of these values

    PENOENT        - Directory not found or path to file not found
    PEACCES       - Not a directory, not empty or in use
    PENOSPC        - Write failed

*****************************************************************************/


/* Remove a directory */
BOOL NU_Remove_Dir(TEXT  *name) 									/*__fn__*/
{
    DROBJ *parent_obj;
    DROBJ *pobj;
    DROBJ *pchild;
    BOOL ret_val;
    TEXT  path[EMAXPATH];
    TEXT  filename[9];
    TEXT  fileext[4];
    COUNT driveno;
    PC_FS_ENTER()     /* Must be last line in declarations */
    CHECK_USER(BOOL, 0) /* Check if a valid user if multitasking */

    parent_obj = NULL;
    pchild = NULL;
    pobj = NULL;
    fs_user->p_errno = 0;
    ret_val = NO;

    if (!pc_parsedrive( &driveno, name ))
    {
        fs_user->p_errno = PENOENT;
        goto return_error;
    }   

    PC_DRIVE_ENTER(driveno, YES)   /* RMDIR is strange so lock the drive */

    /* Get out the filename and d:parent */
    if (!pc_parsepath(path,filename,fileext,name))
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    /* Find the parent and make sure it is a directory \ */
    parent_obj = pc_fndnode(path);
    if (!parent_obj)
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    if (!pc_isadir(parent_obj) || pc_isavol(parent_obj))
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    /* Find the file and init the structure */
    pobj = pc_get_inode(NULL, parent_obj, (UTEXT*)filename, (UTEXT*)fileext);

    if (!pobj)
    {
        fs_user->p_errno = PENOENT;
        goto errex;
    }

    if (!pc_isadir(pobj) || (pobj->finode->opencount > 1))
    {
        fs_user->p_errno = PEACCES;
        goto errex;
    }

    /* Search through the directory. look at all files */
    /* Any file that is not '.' or '..' is a problem */
    /* Call pc_get_inode with NULL to give us an obj */
    ret_val = YES;
    pchild = pc_get_inode(NULL, pobj, (UTEXT*)"*", (UTEXT*)"*");
    if (pchild)
    {
        do 
        {
            if (!(pc_isdot(pchild->finode->fname, pchild->finode->fext) ) )
                if (!(pc_isdotdot(pchild->finode->fname, pchild->finode->fext) ) )
                {
                    fs_user->p_errno = PEACCES;
                    ret_val = NO;
                    goto errex;
                }
        }
        while (pc_get_inode(pchild, pobj, (UTEXT*)"*", (UTEXT*)"*"));
    }
    ret_val = pc_rmnode(pobj);
    if (!ret_val)
    {
        fs_user->p_errno = PENOSPC;
        goto errex;
    }

errex:
    if (pchild)
        pc_freeobj(pchild);
    if (pobj)
        pc_freeobj(pobj);
    if (parent_obj)
    {
        pc_freeobj(parent_obj);
    }
    PC_DRIVE_EXIT(driveno)

return_error:      /* Not only errors return through here. Everything does. */
    /* Restore the kernel state */
    PC_FS_EXIT()
    return(ret_val);
}


/*****************************************************************************
    PC_FAT_SIZE  -  Calculate a disks FAT size based on input parameters


 Description
    Given a drive description including number of reserved sectors (this
    includes block 0), Number of root directory entries. (must be an even
    multiple of 16), cluster size, and

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -