nu_file.c

来自「移植Nuclues_RTC到coldfire5307在diab下编译通过」· C语言 代码 · 共 1,389 行 · 第 1/5 页

C
1,389
字号

                    utemp = n_to_read;
                    while(utemp)
                    {
                        if (utemp > MAXSECTORS)
                            nblocks = MAXSECTORS;
                        else
                            nblocks = (UINT16) utemp;

                        /* READ */
                        PC_DRIVE_IO_ENTER(pdrive->driveno)
                        if ( !pc_bdevsw[pdrive->driveno].io_proc(pdrive->driveno, block_to_read, (UINT8 *)buf, nblocks, YES))
                        {
                            PC_DRIVE_IO_EXIT(pdrive->driveno)
                            fs_user->p_errno = PENOSPC;
                            ret_val = NUF_IO_ERROR;
                            break;
                        }
                        PC_DRIVE_IO_EXIT(pdrive->driveno)

                        utemp -= nblocks;
                        block_to_read += nblocks;
                        buf += (nblocks << 9);
                    }

                    n_bytes = (UINT32) (n_to_read << 9);
                    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 =(UINT32) ((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 += utemp;
                    }
                    pfile->fptr_block = pc_cl2sector(pdrive, pfile->fptr_cluster);
                }
            }
        }       /* while n_left */
        if (ret_val < 0)
        {
            /* Restore pointers and return */
            pfile->fptr = saved_ptr;
            pfile->fptr_block = saved_ptr_block;
            pfile->fptr_cluster = saved_ptr_cluster;
        }
        else
        {
            ret_val = count;
        }
        PC_INODE_EXIT(pfile->pobj->finode)
        PC_DRIVE_EXIT(pdrive->driveno)
    }

    /* Restore the kernel state */
    PC_FS_EXIT()
    return(ret_val);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       NU_Write                                                        
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Attempt to write count bytes from buf to the current file       
*       pointer of file at fd. The file pointer is updated.             
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi
*                                                                       
* INPUTS                                                                
*                                                                       
*       fd                                  File descriptor.            
*       *buf                                Pointer of buffer to write. 
*       count                               Write byte count.           
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       Returns the number of bytes written or negative value on error. 
*       If the return value is negative, the meaning is follows:        
*                                                                       
*       INT32                               A non-negative integer to be
*                                            used as a number of bytes  
*                                            written.                   
*       NUF_BAD_USER                        Not a file user.            
*       NUF_BADPARM                         Invalid parameter specified.
*       NUF_BADFILE                         File descriptor invalid.    
*       NUF_ACCES                           Not a PO_WRONLY or PO_RDWR  
*                                            open flag or file          
*                                            attributes is ARDONLY.     
*       NUF_NOSPC                           Write failed. Presumably    
*                                            because of no space.       
*       NUF_IO_ERROR                        IO error occured.           
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*       fs_user->p_errno is set to one of these values                  
*                                                                       
*       PEBADF                              Invalid file descriptor.    
*       PEACCES                             Attempt to open a read only 
*                                            file or a special          
*                                            (directory) file.          
*       PENOSPC                             Create failed.              
*                                                                       
*************************************************************************/
INT32 NU_Write(INT fd, CHAR *buf, INT32 count)
{
PC_FILE     *pfile;
DDRIVE      *pdrive;
UINT32      block_in_cluster;
UINT16      byte_offset_in_block;
UINT32      next_cluster;
UINT32      saved_ptr;
UINT32      saved_ptr_block;
UINT32      saved_ptr_cluster;
UINT32      ltemp;
UINT32      n_bytes;
UINT32      n_to_write;
UINT32      n_left;
UINT32      n_blocks_left;
UINT16      nblocks;
UINT32      n_clusters;
UINT32      alloced_size;
UINT32      block_to_write;
UINT8       local_buf[512];
INT32       ret_val;
STATUS      status;


    PC_FS_ENTER()     /* Must be last line in declarations */
    CHECK_USER(INT32, NUF_BAD_USER) /* Check if a valid user if multitasking */

    fs_user->p_errno = 0;

    /* Get the FILE. Second argument is ignored */
    if ( (pfile = pc_fd2file(fd)) == NULL )
    {
        fs_user->p_errno = PEBADF;
        ret_val = NUF_BADFILE;
    }
    /* Check the file attributes */
    else if (pfile->pobj->finode->fattribute & ARDONLY)
    {
        fs_user->p_errno = PEACCES;
        ret_val = NUF_ACCES;
    }
    /* Opened for write ? */
    else if ( !((pfile->flag & PO_WRONLY) || (pfile->flag & PO_RDWR)) )
    {
        fs_user->p_errno = PEACCES;
        ret_val = NUF_ACCES;
    }
    /* Return 0 (none written) on bad args */
    else if (!count)
    {
        ret_val = 0;
    }
    /* Return -1 bad parameter */
    else if ( count < 0 || !buf )
    {
        ret_val = NUF_BADPARM;
    }
    else
    {
        pdrive = pfile->pobj->pdrive;
        PC_DRIVE_ENTER(pdrive->driveno, NO)  /* Register drive in use (non excl) */

        /* Only one process may write at a time */
        PC_INODE_ENTER(pfile->pobj->finode, YES)

        /* if the  file is zero sized make sure the current cluster pointer
           is invalid */
        if (!pfile->pobj->finode->fsize)
            pfile->fptr_cluster = 0L;

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

        /* calculate initial values */
        n_left = count;

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

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

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

                n_blocks_left = (UINT32) ((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 = ( UINT32) (1 + 
                ((n_blocks_left + block_in_cluster - 1) >> pdrive->log2_secpalloc));

                if (pdrive->fasize == 8)    /* FAT32 */
                {
                    /* Calculate file total size */
                    ltemp = alloced_size >> pdrive->log2_secpalloc;
                    ltemp >>= 9;  /* Divide by 512 */
                    ltemp += n_clusters;

                    /* Chech the maximum file size(4GB) */
                    if (pdrive->maxfsize_cluster < ltemp)
                    {
                        ret_val = NUF_MAXFILE_SIZE;
                        break;  /* Exit from write loop */
                    }
                }

                /* 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 */

                PC_FAT_ENTER(pdrive->driveno)
                status = pc_alloc_chain(&n_clusters, pdrive, &(pfile->fptr_cluster), n_clusters);
                PC_FAT_EXIT(pdrive->driveno)

                if (status != NU_SUCCESS)
                {
                    ret_val = (INT32)status;
                    break;  /* Exit from write loop */
                }
                /* Calculate the last cluster in this chain. */
                next_cluster = (UINT32) (pfile->fptr_cluster + n_clusters - 1);

                /* link the chain to the directory object if just starting */
               if (!pfile->pobj->finode->fcluster)
                    pfile->pobj->finode->fcluster = pfile->fptr_cluster;

                /* 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 = (UINT32) ((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
              

⌨️ 快捷键说明

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