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

📄 api.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************
    PC_MKDIR    -  Create a directory.

Description
    Create a sudirectory in the path specified by name. Fails if a
    file or directory of the same name already exists or if the path
    is not found.


Returns
    Returns TRUE if it was able to create the directory, otherwise
    it returns FALSE.
    
    If pc_mkdir fails, xn_getlasterror() will be set to one of the following:

        PENOENT     - path to new directory not found
        PEEXIST     - File or Dir already exists by this name.
        PENOSPC     - Drectory create failed
****************************************************************************/

BOOLEAN pc_mkdir(char  *name)                                       /*__fn__*/
{
    DROBJ *pobj;
    DROBJ *parent_obj;
    char  path[EMAXPATH];
    char  filename[FILENAMESIZE];   /* VFAT */
    char  fileext[4];
    BOOLEAN  ret_val;
    int driveno;    
    int p_errno;
    CHECK_MEM(BOOLEAN, 0)   /* Make sure memory is initted */
    OS_FS_ENTER()
    ret_val = FALSE;
    parent_obj = 0;
    pobj = 0;

    p_errno = PENOENT;

    /* Get the drive and make sure it is mounted   */
    driveno = check_drive(name);
    if (driveno < 0)
    {
        OS_FS_EXIT()
        return(FALSE);
    }

    OS_CLAIM_LOGDRIVE(driveno)  /* Register drive in use */
    
    /* Get out the filename and d:parent   */
    if (!pc_parsepath(path,filename,fileext,name))
        goto errex;
#if (VFAT)
    if (!validate_filename(filename, tc_strlen(filename)))
        goto errex;
#else
    if (!validate_filename(filename, 8))
        goto errex;
    if (!validate_filename(fileext, 3))
        goto errex;
#endif

    /* Find the parent and make sure it is a directory \   */
    parent_obj = pc_fndnode(path);
    if (!parent_obj)
        goto errex;

    /* Lock the parent      */
    if (!pc_isadir(parent_obj) ||  pc_isavol(parent_obj))
        goto errex;

    /* Fail if the directory exists   */
    pobj = pc_get_inode(0, parent_obj, (byte*)filename,(byte*) fileext, FALSE);

    if (pobj)
    {
        p_errno = PEEXIST;      /* Exclusive fail */
    }
    else
    {
        pobj = pc_mknode( parent_obj, filename, fileext, ADIRENT);
        if (pobj)
        {
            p_errno = 0;
            ret_val = TRUE;
        }
        else
        {
            p_errno = PENOSPC;
            goto errex;
        }
    }

errex:
    if (pobj)
        pc_freeobj(pobj);
    if (parent_obj)
    {
        pc_freeobj(parent_obj);
    }
    OS_RELEASE_LOGDRIVE(driveno)
    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(ret_val);
}
#endif  /* Subdirs */
#endif  /* Write */

RTFS_FILE(open.c, po_open)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/****************************************************************************
    PO_OPEN -  Open a file.

 Description
    Open the file for access as specified in flag. If creating use mode to
    set the access permissions on the file.

    Flag values are

    PO_BINARY   - Ignored. All file access is binary
    PO_char     - Ignored
    PO_RDONLY   - Open for read only
    PO_RDWR     - Read/write access allowed.
    PO_WRONLY   - Open for write only

    PO_CREAT    - Create the file if it does not exist. Use mode to
                  specify the permission on the file.
    PO_EXCL     - If flag contains (PO_CREAT | PO_EXCL) and the file already
                    exists fail and set xn_getlasterror() to EEXIST
    PO_TRUNC    - Truncate the file if it already exists
    PO_NOSHAREANY   - Fail if the file is already open. If the open succeeds
                    no other opens will succeed until it is closed.
    PO_NOSHAREWRITE-  Fail if the file is already open for write. If the open 
                    succeeds no other opens for write will succeed until it
                    is closed.

    Mode values are

    PS_IWRITE   - Write permitted   
    PS_IREAD    - Read permitted. (Always true anyway)

 Returns
    Returns a non-negative integer to be used as a file descriptor for
    calling read/write/seek/close otherwise it returns -1 and xn_getlasterror() is set to
    one of these values

    PENOENT     - File not found or path to file not found
    PEMFILE     - No file descriptors available (too many files open)
    PEEXIST     - Exclusive access requested but file already exists.
    PEACCESS    - Attempt to open a read only file or a special (directory)
                  file.
    PENOSPC     - Create failed
    PESHARE     - Already open in exclusive mode or we want exclusive
                  and its already open
****************************************************************************/

PCFD po_open(char *name, word flag, word mode)                  /*__fn__*/
{
    PCFD fd;
    PC_FILE *pfile;
    CLUSTERTYPE  cluster;   /* FAT32 */
    DROBJ *parent_obj;
    DROBJ *pobj;
    char  path[EMAXPATH];
    char  filename[FILENAMESIZE];   /* VFAT */
    char  fileext[4];
    int driveno;
    BOOLEAN open_for_write;
#if (RTFS_SHARE)
    BOOLEAN sharing_error;
#endif
    dword ltemp;
    int p_errno;
    CHECK_MEM(PCFD, -1) /* Make sure memory is initted */
    OS_FS_ENTER()

#if (RTFS_SHARE)
    sharing_error = FALSE;
#endif
    parent_obj = 0;

    open_for_write = FALSE;

#if (RTFS_WRITE)
    /* We'll need to know this in a few places.   */
    if(flag & (PO_WRONLY|PO_RDWR))
        open_for_write = TRUE;
#endif

    /* Get the drive and make sure it is mounted   */
    driveno = check_drive(name);
    if (driveno < 0)
    {
        OS_FS_EXIT()
        return(-1);
    }

    if ( (fd = pc_allocfile()) < 0 )    /* Grab a file */
    {
        p_errno = PEMFILE;
        goto errex1;
    }
    
    /* Get the FILE. This will never fail   */
    pfile = pc_fd2file(fd, 0);
    /* Paranoia. Set the obj to null until we have one   */
    pfile->pobj = 0;

    OS_CLAIM_LOGDRIVE(driveno)  /* Register drive in use */

    p_errno = PENOENT;

    /* Get out the filename and d:parent   */
    if (!pc_parsepath(path,filename,fileext,name))
        goto errex;
#if (VFAT)
    if (!validate_filename(filename, tc_strlen(filename)))
        goto errex;
#else
    if (!validate_filename(filename, 8))
        goto errex;
    if (!validate_filename(fileext, 3))
        goto errex;
#endif

    /* Find the parent   */
    parent_obj = pc_fndnode(path);

    if (!parent_obj)
        goto errex;
        
    if (!pc_isadir(parent_obj) ||  pc_isavol(parent_obj))
        goto errex;


    pobj =  pc_get_inode(0, parent_obj,(byte*)filename,(byte*)fileext, FALSE);

    if (pobj)
    {
        /* If we goto exit: we want them linked so we can clean up   */
        pfile->pobj = pobj;         /* Link the file to the object */
#if (RTFS_SHARE)
        /* check the sharing conditions   */
        sharing_error = FALSE;
        if (pobj->finode->opencount != 1)
        {
            /* The file is already open by someone. Lets see if we are
                compatible */
                /* 1. We don't want to share with anyone   */
            if (flag & PO_NOSHAREANY)
                sharing_error = TRUE;
                /* 2. Someone else doesn't want to share   */
            if (pobj->finode->openflags & OF_EXCLUSIVE)
                sharing_error = TRUE;
                /* 3. We want exclusive write but already open for write   */
            if ( open_for_write && (flag & PO_NOSHAREWRITE) &&
                (pobj->finode->openflags & OF_WRITE))
                sharing_error = TRUE;
                /* 4. We want open for write but it's already open for
                    exclusive */
            if ( (open_for_write) && 
                (pobj->finode->openflags & OF_WRITEEXCLUSIVE))
                sharing_error = TRUE;
                /* 5. Open for trunc when already open   */
            if (flag & PO_TRUNC)
                sharing_error = TRUE;
        }
        if (sharing_error)
        {
            p_errno = PESHARE;
            goto errex;
        }
#endif /* RTFS_SHARE */
        if( pc_isadir(pobj) || pc_isavol(pobj) )
        {
            p_errno = PEACCES;      /* is a directory */
            goto errex;
        }
#if (RTFS_WRITE)
        if ( (flag & (PO_EXCL|PO_CREAT)) == (PO_EXCL|PO_CREAT) )
        {
            p_errno = PEEXIST;      /* Exclusive fail */
            goto errex;
        }
        if(open_for_write && (pobj->finode->fattribute & ARDONLY) )
        {
            p_errno = PEACCES;      /* read only file */
            goto errex;
        }
        if (flag & PO_TRUNC)
        {
            cluster = pc_finode_cluster(pobj->pdrive,pobj->finode); /* FAT32 */
            ltemp   = pobj->finode->fsize;

            pc_pfinode_cluster(pobj->pdrive,pobj->finode,0); /* FAT32 */
            pobj->finode->fsize = 0L;
            /* Convert to native. Overwrite the existing inode.Set archive/date  */
            /* Bug fix was:
                if (!pc_update_inode(pobj, TRUE, TRUE))
            */
            if (pc_update_inode(pobj, TRUE, TRUE))
            {
                /* And clear up the space   */
                pc_freechain(pobj->pdrive,cluster);
                pc_flushfat(pobj->pdrive->driveno);
            }
            else
            {
                pc_pfinode_cluster(pobj->pdrive,pobj->finode,cluster); /* FAT32 */
                pobj->finode->fsize = ltemp;
                p_errno = PEACCES;
                goto errex;
            }
        }
#endif
    }
    else    /* File not found */
    {
#if (RTFS_WRITE)
        if (!(flag & PO_CREAT))
        {
            p_errno = PENOENT;      /* File does not exist */
            goto errex;
        }
            /* Do not allow create if write bits not set   */
        if(!open_for_write)
        {
            p_errno = PEACCES;      /* read only file */
            goto errex;
        }
            /* Create for read only if write perm not allowed               */
        pobj = pc_mknode( parent_obj, filename, fileext, (byte) ((mode == PS_IREAD) ? ARDONLY : 0));

        if (!pobj)
        {
            p_errno = PENOSPC;
            goto errex;
        }

        pfile->pobj = pobj;         /* Link the file to the object */
#else   /* Write not built in. Get out */
        p_errno = PENOENT;      /* File does not exist */
        goto errex;
#endif
    }

    /* Set the file sharing flags in the shared finode structure   */
    /* clear flags if we just opened it .                          */
    if (pobj->finode->opencount == 1)
        pobj->finode->openflags = 0;
#if (RTFS_WRITE)
    if (open_for_write)
    {
        pobj->finode->openflags |= OF_WRITE;
        if (flag & PO_NOSHAREWRITE)
            pobj->finode->openflags |= OF_WRITEEXCLUSIVE;
    }
    if (flag & PO_NOSHAREANY)
        pobj->finode->openflags |= OF_EXCLUSIVE;
#endif
    pfile->flag = flag;         /* Access flags */
    pfile->fptr = 0L;           /* File pointer */

    /* Set the cluster and block file pointers   */
    _synch_file_ptrs(pfile);

    p_errno = 0;
    if (parent_obj)
    {
        pc_freeobj(parent_obj);
    }
    OS_RELEASE_LOGDRIVE(driveno)
    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(fd);
errex:
    pc_freefile(fd);
    if (parent_obj)
    {
        pc_freeobj(parent_obj);
    }
    OS_RELEASE_LOGDRIVE(driveno)
errex1:
    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(-1);
}

RTFS_FILE(read.c, po_read)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif


⌨️ 快捷键说明

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