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

📄 api.c

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


#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   */
            ltemp = n_clusters << pdrive->log2_secpalloc; ltemp <<= 9;
            alloced_size += ltemp;
        }
        else        /* Not extending the file. (writing inside 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 */
                
            /* 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) )
        {
            block_in_cluster = (word) (pfile->fptr & pdrive->byte_into_cl_mask);
            block_in_cluster >>= 9;

⌨️ 快捷键说明

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