📄 api.c
字号:
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 + -