📄 nu_file.c
字号:
{
/* 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 (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;
pfile->flag = flag; /* Access flags */
pfile->fptr = 0L; /* File pointer */
/* Set the cluster and block file pointers */
_synch_file_ptrs(pfile);
if (flag & PO_APPEND)
{
/* Call the internal seek routine to set file pointer to file end */
_po_lseek(pfile, 0, PSEEK_END);
}
fs_user->p_errno = 0;
}
PC_INODE_EXIT(parent_obj->finode)
pc_freeobj(parent_obj);
}
}
PC_DRIVE_EXIT(driveno)
}
/* Restore the kernel state */
PC_FS_EXIT()
return(fd);
}
/************************************************************************
* FUNCTION
*
* NU_Read
*
* 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.
*
* AUTHOR
*
* Takahiro Takahashi
*
* INPUTS
*
* fd File descriptor
* buf Buffer to read data.
* count Number of read bytes.
*
* OUTPUTS
*
* Returns the number of bytes read or negative value on error.
*
* INT32 A non-negative integer to be
* used as a number of bytes
* read.
* NUF_BAD_USER Not a file user.
* NUF_BADPARM Invalid parameter specified.
* NUF_BADFILE Invalid file descriptor.
* NUF_ACCES Open flag is PO_WRONLY.
* 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.
* PENOSPC Create failed.
*
*************************************************************************/
INT32 NU_Read(INT fd, CHAR *buf, INT32 count)
{
PC_FILE *pfile;
UINT32 block_in_cluster;
UINT16 byte_offset_in_block;
UINT32 n_bytes;
UINT32 next_cluster;
UINT32 n_clusters;
UINT32 block_to_read;
DDRIVE *pdrive;
UINT32 saved_ptr;
UINT32 saved_ptr_block;
UINT32 saved_ptr_cluster;
INT32 n_left;
UINT32 n_to_read;
UINT32 utemp;
UINT16 nblocks;
UINT8 local_buf[512];
INT32 ret_val;
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;
ret_val = 0;
/* Get the FILE. Second argument is ignored */
if ((pfile = pc_fd2file(fd)) == NULL)
{
fs_user->p_errno = PEBADF;
ret_val = NUF_BADFILE;
}
/* Opened for read ? */
else if (pfile->flag & PO_WRONLY)
{
fs_user->p_errno = PEACCES;
ret_val = NUF_ACCES;
}
/* return -1 if bad arguments */
else if ( !buf || count < 0)
{
ret_val = NUF_BADPARM;
}
/* Dont read if done */
else if ( (pfile->fptr < pfile->pobj->finode->fsize) && (count) )
{
/* Move ddrive pointer to local. */
pdrive = pfile->pobj->pdrive;
/* Register Drive in use */
PC_DRIVE_ENTER(pdrive->driveno, NO)
/* Grab exclusive access to the drobj */
PC_INODE_ENTER(pfile->pobj->finode, YES)
/* 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 = (INT32) (pfile->pobj->finode->fsize - pfile->fptr);
ret_val = n_left = count;
while (n_left) /* Loop until read specified count bytes */
{
block_in_cluster = (UINT32) (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 = (UINT32) ( (n_left + 511) >> 9 );
n_clusters =(UINT32) ((n_to_read+pdrive->secpalloc-1) >> pdrive->log2_secpalloc);
/* how many contiguous clusters can we get ? <= n_clusters */
PC_FAT_ENTER(pdrive->driveno)
ret_val = pc_get_chain(pdrive, pfile->fptr_cluster,
&next_cluster, n_clusters);
PC_FAT_EXIT(pdrive->driveno)
if (ret_val < 0)
{
fs_user->p_errno = PENOSPC;
break;
}
n_clusters = ret_val;
/* Are we inside a block */
if ( (pfile->fptr & 0x1ffL) || (n_left < 512) )
{
byte_offset_in_block = (UINT16) (pfile->fptr & 0x1ffL);
/* READ */
PC_DRIVE_IO_ENTER(pdrive->driveno)
if ( !pc_bdevsw[pdrive->driveno].io_proc(pdrive->driveno, block_to_read, local_buf, (UINT16) 1, YES) )
{
PC_DRIVE_IO_EXIT(pdrive->driveno)
fs_user->p_errno = PENOSPC;
ret_val = NUF_IO_ERROR;
break;
}
PC_DRIVE_IO_EXIT(pdrive->driveno)
/* Copy source data to the local buffer */
n_bytes = (UINT32) (512 - byte_offset_in_block);
if (n_bytes > (UINT32)n_left)
n_bytes = (UINT32)n_left;
copybuff((UINT8 *)buf, &local_buf[byte_offset_in_block], (INT)n_bytes);
buf += n_bytes;
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 += 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 = (UINT32) (n_clusters << pdrive->log2_secpalloc);
/* subtract out any leading blocks */
n_to_read -= block_in_cluster;
/* How many blocks yet to read */
utemp = (UINT32) (n_left >> 9);
/* take the smallest of the two */
if (n_to_read > utemp)
n_to_read = utemp;
if (n_to_read)
{
/* If we get here we need to read contiguous blocks */
block_to_read = pfile->fptr_block + block_in_cluster;
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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -