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

📄 api.c

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


word _po_read(PCFD fd,  byte *buf, word count)                   /*__fn__*/
{
    PC_FILE *pfile;
    word block_in_cluster;
    word byte_offset_in_block;
    word n_bytes;
    CLUSTERTYPE  next_cluster;/* FAT32 */
    CLUSTERTYPE  n_clusters;  /* FAT32 */
    dword  block_to_read;
    DDRIVE *pdrive;
    dword  saved_ptr;
    dword  saved_ptr_block;     
    CLUSTERTYPE  saved_ptr_cluster;        /* FAT32 */
    word n_left;
    word n_to_read;
    CLUSTERTYPE utemp;
    BLKBUFF *local_buf;                     /* FAT32 */
    int p_errno;
    word ret_val;
    CHECK_MEM(word, ~0) /* Make sure memory is initted */
    OS_FS_ENTER()

    p_errno = 0;    

    /* Get the FILE.   */
    if ( (pfile = pc_fd2file(fd, 0)) == 0)
    {
        p_errno = PEBADF;
        ret_val = (word) ~0;
        goto return_error;
    }
    /* return 0 bytes read if bad arguments   */
    if (!count || !buf)
    {
        ret_val = 0;
        goto return_error;
    }


    OS_CLAIM_FSCRITICAL()
    if (pfile->fptr >= pfile->pobj->finode->fsize)  /* Dont read if done */
    {
        ret_val = 0;
        OS_RELEASE_FSCRITICAL()
        goto return_error;
    }
    OS_RELEASE_FSCRITICAL()

    pdrive = pfile->pobj->pdrive;
    OS_CLAIM_LOGDRIVE(pdrive->driveno)  /* Register Drive in use */
    /* Grab exclusive access to the drobj   */

    /* Set the cluster and block file pointers if not already set   */
    _synch_file_ptrs(pfile);

    saved_ptr           = pfile->fptr;
    saved_ptr_block = pfile->fptr_block;        
    saved_ptr_cluster   = pfile->fptr_cluster;      


    /* Truncate the read count if we need to   */
    if ( (pfile->fptr + count) >= pfile->pobj->finode->fsize)
        count = (word) (pfile->pobj->finode->fsize - pfile->fptr);

    n_left = count;

    while (n_left)
    {
        block_in_cluster = (word) (pfile->fptr & pdrive->byte_into_cl_mask);
        block_in_cluster >>= 9;
        block_to_read = pfile->fptr_block + block_in_cluster;

        /* how many clusters are left   */
        n_to_read = (word) ( (n_left + 511) >> 9 );
        n_clusters = (CLUSTERTYPE) ((n_to_read+pdrive->secpalloc-1) >> pdrive->log2_secpalloc); /* FAT32 */

        /* how many contiguous clusters can we get ? <= n_clusters   */
        n_clusters = pc_get_chain(pdrive, pfile->fptr_cluster,
                                        &next_cluster, n_clusters);

        if (!n_clusters)
            goto ret_bad_f;

        /* Are we inside a block   */
        if ( (pfile->fptr & 0x1ffL) || (n_left < 512) )
        {
            byte_offset_in_block = (word) (pfile->fptr & 0x1ffL);
            /* READ - Use the block buffer pool to read for us   */
            local_buf = pc_read_blk(pdrive,  block_to_read);
            if (!local_buf)
                goto ret_bad_f;
            /* Copy source data to the local buffer   */
            n_bytes = (word) (512 - byte_offset_in_block);
            if (n_bytes > n_left)
                n_bytes = n_left;
            copybuff(buf, &(local_buf->data[byte_offset_in_block]), n_bytes);
            /* Release the buffer. and discard it   */
            pc_free_buf(local_buf, TRUE);
            buf += n_bytes;
            n_left = (word) (n_left - n_bytes);
            pfile->fptr += n_bytes;
            
            /* Are we on a cluster boundary  ?   */
            if (!(pfile->fptr & pdrive->byte_into_cl_mask))
            {
                if (--n_clusters)           /* If contiguous */
                {
                    pfile->fptr_block += pdrive->secpalloc;
                    pfile->fptr_cluster += (CLUSTERTYPE)1;
                }
                else
                {
                    pfile->fptr_cluster = next_cluster;
                    pfile->fptr_block = pc_cl2sector(pdrive, next_cluster);
                }   /* if (--nclusters) {} else {}; */
            }       /* if (!(pfile->fptr & pdrive->byte_into_cl_mask)) */
        }           /* if ( (pfile->fptr & 0x1ff) || (n_left < 512) ) */
        else
        {
            /* Read as many blocks as possible             */
                /* How many blocks in the current chain    */
            n_to_read = (word) (n_clusters << pdrive->log2_secpalloc);
                /* subtract out any leading blocks   */
            n_to_read = (word) (n_to_read - block_in_cluster);
                /* How many blocks yet to read   */
            utemp = (word) (n_left >> 9);
                /* take the smallest of the two   */
            if (n_to_read > (word)utemp)
                n_to_read = (word)utemp;

            if (n_to_read)
            {
            /* If we get here we need to read contiguous blocks   */
                block_to_read = pfile->fptr_block + block_in_cluster;

            /* READ   */
                if (!devio_read(pdrive->driveno, block_to_read, buf, n_to_read, FALSE))
                    goto ret_bad_f;
                n_bytes = (word) (n_to_read << 9);
                buf += n_bytes;
                n_left= (word)(n_left - n_bytes);
                pfile->fptr += n_bytes;

                /* if we advanced to a cluster boundary advance the 
                    cluster pointer */
                /* utemp ==s how many clusters we read   */
                utemp =(word) ((n_to_read+block_in_cluster) >> pdrive->log2_secpalloc);

                if (utemp == n_clusters)
                {
                    pfile->fptr_cluster = next_cluster;
                }
                else
                {
                    /* advance the pointer as many as we read   */
                    pfile->fptr_cluster =  (CLUSTERTYPE) (pfile->fptr_cluster + utemp); /* FAT32 */
                }
                pfile->fptr_block = pc_cl2sector(pdrive, pfile->fptr_cluster);
            }
        }
    }       /* while n_left */

    OS_RELEASE_LOGDRIVE(pdrive->driveno)

    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(count);

ret_bad_f:
    /* Restore pointers and return   */
    pfile->fptr = saved_ptr;
    pfile->fptr_block = saved_ptr_block;        
    pfile->fptr_cluster = saved_ptr_cluster;        
    p_errno = PENOSPC;
    OS_RELEASE_LOGDRIVE(pdrive->driveno)
    ret_val = (word) ~0;
return_error:
    /* Restore the kernel state   */
    set_errno(p_errno);
    OS_FS_EXIT()
    return(ret_val);
}

RTFS_FILE(write.c, po_write)

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

/***************************************************************************
    PO_WRITE    -  Write to a file.

 Description
    Attempt to write count bytes from buf to the current file pointer of file
    at fd. The file pointer is updated.

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

    PENBADF     - File descriptor invalid or open read only
    PENOSPC     - Write failed. Presumably because of no space

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


//DM: added: po_write() shell and renamed original to _po_write()
/***************************************************************************
AM: Created shell routine with return value of int so will work properly under
    32 bit compile for negative number.      
****************************************************************************/

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

int po_write(PCFD fd, byte *buf, word count)                   /*__fn__*/
{
#if (RTFS_WRITE)
    word return_value = _po_write(fd, buf, count);
    if (return_value == 0xFFFF)
        return(-1);
    else
        return(return_value);
#else
    return(-1);
#endif
}



#if (RTFS_WRITE)
word _po_write(PCFD fd, byte *buf, word count)                   /*__fn__*/
{
    PC_FILE *pfile;
    DDRIVE *pdrive;
    word block_in_cluster;
    word byte_offset_in_block;
    dword  saved_ptr;
    dword  saved_ptr_block;     
    CLUSTERTYPE  next_cluster;      /* FAT32 */
    CLUSTERTYPE  saved_ptr_cluster;   /* FAT32 */
    CLUSTERTYPE  n_clusters;            /* FAT32 */

    dword  ltemp;
    word n_bytes;
    word n_to_write;
    word n_left;
    word n_blocks_left;
    dword  alloced_size;
    dword  block_to_write;
    BLKBUFF *local_buf;
    int p_errno;
    word ret_val;
    CHECK_MEM(word, ~0) /* Make sure memory is initted */

        /* Return 0 (none written) on bad args   */
    if (!count || !buf)
    {
        return(0);
    }

    OS_FS_ENTER()

    p_errno = 0;

    /* Get the FILE. must be open for write   */
    pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
    if (!pfile)
    {
        p_errno = PEBADF;
        ret_val = (word) ~0;
        goto return_error;
    }
    pdrive = pfile->pobj->pdrive;
    OS_CLAIM_LOGDRIVE(pdrive->driveno)  /* Register drive in use (non excl) */
    /* Only one process may write at a time   */

    /* 
    * Note the file's finode is LOCKED below so the code needn't be 
    * reentrant relative to the finode. 
    */
    /* if the  file is zero sized make sure the current cluster pointer
        is invalid */
    if (!pfile->pobj->finode->fsize)
        pfile->fptr_cluster = 0;

    /* 11-20-99 - Bug fix - to register file size and flush if we run out of space */ 
    /* 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);

    /* 11-20-99 - End Bug fix section : more below  */ 

    /* Set the cluster and block file pointers if not already set   */
    _synch_file_ptrs(pfile);
    saved_ptr = pfile->fptr;
    saved_ptr_block = pfile->fptr_block;        
    saved_ptr_cluster = pfile->fptr_cluster;        
    /* Seek to the end if append mode   */
    if (pfile->flag & PO_APPEND)
    {
        if (pfile->pobj->finode->fsize)
        {
            if (_po_lseek(pfile, 0L, PSEEK_END) == -1L)
                goto ret_bad_f;
            _synch_file_ptrs(pfile);
        }
    }


    /* calculate initial values   */
    n_left = count;

    /* 11-20-99 - Bug fix: moved alloced_size calculation to above append */ 
    /* 11-20-99 - End Bug fix section : more below  */ 

    while (n_left)
    {
        block_in_cluster = (word) (pfile->fptr & pdrive->byte_into_cl_mask);
        block_in_cluster >>= 9;

        if (pfile->fptr >= alloced_size)
        {
            /* Extending the file   */

            n_blocks_left = (word) ((n_left + 511) >> 9);
            /* how many clusters are left-
            *  assume 1 for the current cluster.
            *   subtract out the blocks in the current
            *   round up by adding secpalloc-1 and then
            *   divide by sectors per cluster

            |  n_clusters = 1 + 
            |   (n_blocks_left-
            |       (pdrive->secpalloc-block_in_cluster)
            |       + pdrive->secpalloc-1) >> pdrive->log2_secpalloc;
                ==>
            */
            n_clusters = ( CLUSTERTYPE ) (1 + /* FAT32 */
            ((n_blocks_left + block_in_cluster -1) >> pdrive->log2_secpalloc));/* FAT32 */

            /* Call pc_alloc_chain to build a chain up to n_cluster clusters
                long. Return the first cluster in pfile->fptr_cluster and
                return the # of clusters in the chain. If pfile->fptr_cluster
                is non zero link the current cluster to the new one */

            n_clusters = pc_alloc_chain(pdrive, &(pfile->fptr_cluster), n_clusters);

            if (!n_clusters)
                goto ret_bad_f;

            /* Calculate the last cluster in this chain.   */
            next_cluster = (CLUSTERTYPE) (pfile->fptr_cluster + n_clusters -1);/* FAT32 */

            /* link the chain to the directory object if just starting   */
            if (!pc_finode_cluster(pfile->pobj->pdrive,pfile->pobj->finode))/* FAT32 */
                pc_pfinode_cluster(pfile->pobj->pdrive,pfile->pobj->finode,pfile->fptr_cluster);/* FAT32 */
            
            /* calculate the new block pointer   */
            pfile->fptr_block = pc_cl2sector(pdrive, pfile->fptr_cluster);
    
            /* calculate amount of space used by the file   */

⌨️ 快捷键说明

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