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

📄 api.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                {
                    ret_val = FALSE;
                    p_errno = PENOSPC;
                    goto errex;
                }
            }
            /* Set ptr_cluster to last in chain so read&write will work right   */
            pfile->fptr_cluster = last_cluster_in_chain;
            if (last_cluster_in_chain)
                pfile->fptr_block = pc_cl2sector(pdrive, last_cluster_in_chain);
            else
                pfile->fptr_block = 0;
            pfile->at_eof = TRUE;
        }
        else        /* Simple case. we aren't on a cluster boundary. Just free*/
        {           /* The chain beyond us and terminate the list */
            last_cluster_in_chain = pfile->fptr_cluster;
            first_cluster_to_release = pc_clnext(pdrive, pfile->fptr_cluster);
            pfile->at_eof = TRUE;
        }

        /*  Now update the directory entry.   */
        pfile->pobj->finode->fsize = offset;
        if (!offset)    /* If the file goes to zero size unlink the chain */
        {
            pc_pfinode_cluster(pfile->pobj->pdrive,pfile->pobj->finode,0);/* FAT32 */
            pfile->fptr_cluster = 0;
            pfile->fptr_block = 0;
            pfile->fptr = 0;
            pfile->at_eof = FALSE;
            /* We're freeing the whole chain so we don't mark last_cluster in chain   */
            last_cluster_in_chain = 0;
        }
        /* Convert to native. Overwrite the existing inode.Set archive/date  */
        if (!pc_update_inode(pfile->pobj, TRUE, TRUE))
        {
            ret_val = FALSE;
            p_errno = PENOSPC;
            goto errex;
        }

        /* Terminate the chain and free the lost chain part   */

        /* Free the rest of the chain   */
        if (first_cluster_to_release)
        {
            /* Release the chain   */
            pc_freechain(pfile->pobj->pdrive, first_cluster_to_release);
        }
        /* Null terminate the chain   */
        if (last_cluster_in_chain)
        {
            if (!pc_pfaxxterm(pdrive, last_cluster_in_chain)) /* FAT32 */
            {
                ret_val = FALSE;
                p_errno = PENOSPC;
            }
        }

        if (!pc_flushfat(pfile->pobj->pdrive->driveno))
        {
            ret_val = FALSE;
            p_errno = PENOSPC;
        }
    }

errex:
    OS_RELEASE_LOGDRIVE(pdrive->driveno)
return_error:   /* No only errors return through here. Everything does. */
    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(ret_val);
}
#endif
RTFS_FILE(intseek.c, _po_lseek)

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

/**************************************************************************
    _PO_LSEEK   -  Move file pointer (internal)

 Description
    Behaves as po_lseek but takes a file instead of a file descriptor.
    
    Attempting to seek beyond end of file puts the file pointer one
    byte past eof. 
    
    All setting up such as drive_enter and drobj_enter should have been done
    before calling here. 

    Called By:
    
    po_lseek and po_truncate.

 Returns
    Returns the new offset or -1 on error.

    If the return value is -1 xn_getlasterror() will be set with one of the following:

    PENBADF     - File descriptor invalid
    PEINVAL     - Seek to negative file pointer attempted.

*****************************************************************************/
/* 
* Note: when this routine is caled the file's finode is LOCKED so the code
* needn't be reentrant relative to the finode. 
*/

long _po_lseek(PC_FILE *pfile, long offset, int origin)         /*__fn__*/
{
    long    file_pointer;
    DDRIVE *pdrive;
    BOOLEAN past_file;
    int  log2_bytespcluster;
    dword  ltemp;
    dword  ltemp2;
    CLUSTERTYPE  n_clusters_to_seek;    /* FAT32 */
    CLUSTERTYPE  n_clusters;/* FAT32 */
    CLUSTERTYPE  first_cluster;      /* FAT32 */
    long    ret_val;
    dword  alloced_size;
    int p_errno;

    p_errno = 0;    

    pdrive = pfile->pobj->pdrive;
    /* If file is zero size'd. were there   */
    if (!(pfile->pobj->finode->fsize))
    {
        ret_val = 0L;
        goto errex;
    }

    if (origin == PSEEK_SET)        /*  offset from begining of file */
        file_pointer = offset;
    else if (origin == PSEEK_CUR)   /* offset from current file pointer */
    {
        file_pointer = (long) pfile->fptr;
        file_pointer += offset;
    }
    else if (origin == PSEEK_END)   /*  offset from end of file */
    {
        file_pointer = (long) pfile->pobj->finode->fsize;
        file_pointer += offset;
    }
    else    /* Illegal origin */
    {
        p_errno = PEINVAL;
        ret_val = -1L;
        goto errex;
    }

    if (file_pointer < 0L)
    {
        p_errno = PEINVAL;
        ret_val = -1L;
        goto errex;
    }

    if (file_pointer >= (long) pfile->pobj->finode->fsize)
    {
        file_pointer = (long) pfile->pobj->finode->fsize;
        past_file = TRUE;
    }
    else
        past_file = FALSE;

    log2_bytespcluster = (int) (pdrive->log2_secpalloc + 9);

    /* How many clusters do we need to seek                       */
    /* use the current cluster as the starting point if we can    */
    if (file_pointer >= (long)pfile->fptr)
    {
        first_cluster = pfile->fptr_cluster;

        ltemp =  file_pointer;
        if (past_file)
        {
            /* If seeking past eof reduce the seek count by one since we can't 
                really seek past EOF */
            ltemp -= 1;
        }
        ltemp >>= log2_bytespcluster;
        ltemp2 = pfile->fptr  >> log2_bytespcluster;
        /* If this algorithm was run twice n_clusters_to_seek would
            end up -1. Which would still work but spin 64K times.
            Thanks top Morgan Woodson of EMU systems for the patch */
        if (ltemp >= ltemp2)
            n_clusters_to_seek = (CLUSTERTYPE) (ltemp - ltemp2); /* FAT32 */
        else
            n_clusters_to_seek = (word) 0;
    }
    else
    {
        /* seek from the beginning    */
        /* seek from the beginning    */
        first_cluster = pc_finode_cluster(pdrive,pfile->pobj->finode);/* FAT32 */
        ltemp = file_pointer >> log2_bytespcluster;
        n_clusters_to_seek = (CLUSTERTYPE) ltemp; /* FAT32 */
    }

    while (n_clusters_to_seek)
    {
        n_clusters = pc_get_chain(pdrive, first_cluster,
                                &first_cluster, n_clusters_to_seek);

        if (!n_clusters)
        {
            p_errno = PEINVAL;
            ret_val = -1L;
            goto errex;
        }
    
        n_clusters_to_seek = (CLUSTERTYPE) (n_clusters_to_seek - n_clusters);
    }

    pfile->fptr_cluster = first_cluster;
    pfile->fptr_block = pc_cl2sector(pdrive, first_cluster);
    pfile->fptr= file_pointer;

    /* If seeking to the end of file see if we are beyond the allocated size of 
        the file. If we are we set the at_eof flag so we know to try to move the
        cluster pointer in case another file instance extends the file */
    if (past_file)
    {
        /* Round the file size up to its cluster size by adding in clustersize-1
            and masking off the low bits */
        alloced_size =  (pfile->pobj->finode->fsize + pdrive->byte_into_cl_mask) &
                        ~(pdrive->byte_into_cl_mask);
        /* If the file pointer is beyond the space allocated to the file note it
            since we may need to adjust this file's cluster and block pointers
            later if someone else extends the file behind our back */
        if (pfile->fptr >= alloced_size)
            pfile->at_eof = TRUE;
        else
            pfile->at_eof = FALSE;
    }
    else
        pfile->at_eof = FALSE;

    ret_val = pfile->fptr;
errex:
                    /* No only errors return through here. Everything does.   */
    set_errno(p_errno);
    return(ret_val);
}

RTFS_FILE(intflush.c, _po_flush)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/* 
* Note: when this routine is caled the file's finode is LOCKED so the code
* needn't be reentrant relative to the finode. 
*/
/* Internal version of po_flush() called by po_flush and po_close   */
BOOLEAN _po_flush(PC_FILE *pfile)                                       /*__fn__*/
{
    BOOLEAN ret_val;
    ret_val = TRUE;
    /* Convert to native. Overwrite the existing inode.Set archive/date  */
    if (pfile->needs_flush)
    {
        if (pc_update_inode(pfile->pobj, TRUE, TRUE))
        {
            pfile->needs_flush = FALSE;
            /* Flush the file allocation table   */
            if (!pc_flushfat(pfile->pobj->pdrive->driveno))
                ret_val = FALSE;
        }
    }
    return(ret_val);
}

#endif
RTFS_FILE(flush.c, po_flush)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/****************************************************************************
    PO_FLUSH  -  Flush a file.

 Description
    Flush the file updating the disk.

 Returns
    Returns TRUE if all went well otherwise it returns FALSE and xn_getlasterror() is set to
    one of these values

    PENBADF - Invalid file descriptor
    PENOSPC - IO error occured
****************************************************************************/

BOOLEAN po_flush(PCFD fd)                                           /*__fn__*/
{
    PC_FILE *pfile;
    BOOLEAN ret_val;
    int  p_errno;
    CHECK_MEM(BOOLEAN, 0)   /* Make sure memory is initted */
    OS_FS_ENTER()

    /* Start by assuming failure   */
    ret_val = FALSE;
    p_errno = PEBADF;   

    /* Get the FILE. must be open for write   */
    pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
    if (pfile)
    {
        OS_CLAIM_LOGDRIVE(pfile->pobj->pdrive->driveno)  /* Register drive in use */
        /* Claim exclusive access on flush   */
        ret_val = _po_flush(pfile);
        if (!ret_val)
            p_errno = PENOSPC;  
        OS_RELEASE_LOGDRIVE(pfile->pobj->pdrive->driveno)
    }
    /* Restore the kernel state   */
    set_errno(p_errno);

    OS_FS_EXIT()
    return(ret_val);
}
#endif

RTFS_FILE(close.c, po_close)

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

/****************************************************************************
    PO_CLOSE  -  Close a file.

 Description
    Close the file updating the disk and freeing all core associated with FD.

 Returns
    Returns 0 if all went well otherwise it returns -1 and xn_getlasterror() is set to
    one of these values

    PENBADF - Invalid file descriptor
    PENOSPC - IO error occured
****************************************************************************/

int po_close(PCFD fd)                                               /*__fn__*/
{
    PC_FILE *pfile;
    int ret_val;
    int driveno;
    int  p_errno;
    CHECK_MEM(int, -1)  /* Make sure memory is initted */
    OS_FS_ENTER()


    if ( (pfile = pc_fd2file(fd, 0)) == 0)
    {
        p_errno = PEBADF;
        ret_val = -1;
    }
    else
    {
        driveno = pfile->pobj->pdrive->driveno;
        OS_CLAIM_LOGDRIVE(driveno)  /* Register drive in use */
        ret_val = 0;
        p_errno = 0;    
#if (RTFS_WRITE)
        if (pfile->flag & ( PO_RDWR | PO_WRONLY ) )
        {
            if (!_po_flush(pfile))
            {
                p_errno = PENOSPC;  
                ret_val = -1;
            }
        }
#endif
        /* Release the FD and its core   */
        pc_freefile(fd);
        OS_RELEASE_LOGDRIVE(driveno)
    }
    set_errno(p_errno);
    /* Restore the kernel state   */
    OS_FS_EXIT()
    return(ret_val);
}

RTFS_FILE(mv.c, pc_mv)

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


/***************************************************************************
    PC_MV 

⌨️ 快捷键说明

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