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

📄 api.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 */


/****************************************************************************
    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);
}



/****************************************************************************
    PO_READ -  Read from a file.

 Description
    Attempt to read count bytes from the current file pointer of file at fd
    and put them in buf. The file pointer is updated.

 Returns
    Returns the number of bytes read or -1 on error.
    If the return value is ((word) ~0) (word) -1 xn_getlasterror() will be set
    with one of the following:

    PENBADF     - File descriptor invalid
    PENOSPC     - File IO error
*****************************************************************************/

//DM: added: po_read() shell and renamed original to _po_read()
/****************************************************************************
AM: To fix for 32 bit compile, created a shell which returns an int value so
    that a comparison to -1 will work under 32 bits.  Renamed original to _po_read.
*****************************************************************************/

word _po_read(PCFD fd,  byte *buf, word count);


int po_read(PCFD fd,  byte *buf, word count)                   /*__fn__*/
{
    word  return_value;
    
    return_value = _po_read(fd, buf, count);
    if (return_value == 0xFFFF)

⌨️ 快捷键说明

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