📄 api.c
字号:
{
if (!pc_pfaxxterm(pdrive, last_cluster_in_chain)) /* FAT32 */
{
ret_val = FALSE;
p_errno = PENOSPC;
}
}
if (!pc_flushfat(pfile->pobj->pdrive->driveno))
{
ret_val = FALSE;
p_errno = PENOSPC;
}
}
errex:
OS_RELEASE_LOGDRIVE(pdrive->driveno)
return_error: /* No only errors return through here. Everything does. */
/* Restore the kernel state */
set_errno(p_errno);
OS_FS_EXIT()
return(ret_val);
}
#endif
RTFS_FILE(intseek.c, _po_lseek)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/**************************************************************************
_PO_LSEEK - Move file pointer (internal)
Description
Behaves as po_lseek but takes a file instead of a file descriptor.
Attempting to seek beyond end of file puts the file pointer one
byte past eof.
All setting up such as drive_enter and drobj_enter should have been done
before calling here.
Called By:
po_lseek and po_truncate.
Returns
Returns the new offset or -1 on error.
If the return value is -1 xn_getlasterror() will be set with one of the following:
PENBADF - File descriptor invalid
PEINVAL - Seek to negative file pointer attempted.
*****************************************************************************/
/*
* Note: when this routine is caled the file's finode is LOCKED so the code
* needn't be reentrant relative to the finode.
*/
long _po_lseek(PC_FILE *pfile, long offset, int origin) /*__fn__*/
{
long file_pointer;
DDRIVE *pdrive;
BOOLEAN past_file;
int log2_bytespcluster;
dword ltemp;
dword ltemp2;
CLUSTERTYPE n_clusters_to_seek; /* FAT32 */
CLUSTERTYPE n_clusters;/* FAT32 */
CLUSTERTYPE first_cluster; /* FAT32 */
long ret_val;
dword alloced_size;
int p_errno;
p_errno = 0;
pdrive = pfile->pobj->pdrive;
/* If file is zero size'd. were there */
if (!(pfile->pobj->finode->fsize))
{
ret_val = 0L;
goto errex;
}
if (origin == PSEEK_SET) /* offset from begining of file */
file_pointer = offset;
else if (origin == PSEEK_CUR) /* offset from current file pointer */
{
file_pointer = (long) pfile->fptr;
file_pointer += offset;
}
else if (origin == PSEEK_END) /* offset from end of file */
{
file_pointer = (long) pfile->pobj->finode->fsize;
file_pointer += offset;
}
else /* Illegal origin */
{
p_errno = PEINVAL;
ret_val = -1L;
goto errex;
}
if (file_pointer < 0L)
{
p_errno = PEINVAL;
ret_val = -1L;
goto errex;
}
if (file_pointer >= (long) pfile->pobj->finode->fsize)
{
file_pointer = (long) pfile->pobj->finode->fsize;
past_file = TRUE;
}
else
past_file = FALSE;
log2_bytespcluster = (int) (pdrive->log2_secpalloc + 9);
/* How many clusters do we need to seek */
/* use the current cluster as the starting point if we can */
if (file_pointer >= (long)pfile->fptr)
{
first_cluster = pfile->fptr_cluster;
ltemp = file_pointer;
if (past_file)
{
/* If seeking past eof reduce the seek count by one since we can't
really seek past EOF */
ltemp -= 1;
}
ltemp >>= log2_bytespcluster;
ltemp2 = pfile->fptr >> log2_bytespcluster;
/* If this algorithm was run twice n_clusters_to_seek would
end up -1. Which would still work but spin 64K times.
Thanks top Morgan Woodson of EMU systems for the patch */
if (ltemp >= ltemp2)
n_clusters_to_seek = (CLUSTERTYPE) (ltemp - ltemp2); /* FAT32 */
else
n_clusters_to_seek = (word) 0;
}
else
{
/* seek from the beginning */
/* seek from the beginning */
first_cluster = pc_finode_cluster(pdrive,pfile->pobj->finode);/* FAT32 */
ltemp = file_pointer >> log2_bytespcluster;
n_clusters_to_seek = (CLUSTERTYPE) ltemp; /* FAT32 */
}
while (n_clusters_to_seek)
{
n_clusters = pc_get_chain(pdrive, first_cluster,
&first_cluster, n_clusters_to_seek);
if (!n_clusters)
{
p_errno = PEINVAL;
ret_val = -1L;
goto errex;
}
n_clusters_to_seek = (CLUSTERTYPE) (n_clusters_to_seek - n_clusters);
}
pfile->fptr_cluster = first_cluster;
pfile->fptr_block = pc_cl2sector(pdrive, first_cluster);
pfile->fptr= file_pointer;
/* If seeking to the end of file see if we are beyond the allocated size of
the file. If we are we set the at_eof flag so we know to try to move the
cluster pointer in case another file instance extends the file */
if (past_file)
{
/* 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);
/* If the file pointer is beyond the space allocated to the file note it
since we may need to adjust this file's cluster and block pointers
later if someone else extends the file behind our back */
if (pfile->fptr >= alloced_size)
pfile->at_eof = TRUE;
else
pfile->at_eof = FALSE;
}
else
pfile->at_eof = FALSE;
ret_val = pfile->fptr;
errex:
/* No only errors return through here. Everything does. */
set_errno(p_errno);
return(ret_val);
}
RTFS_FILE(intflush.c, _po_flush)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/*
* Note: when this routine is caled the file's finode is LOCKED so the code
* needn't be reentrant relative to the finode.
*/
/* Internal version of po_flush() called by po_flush and po_close */
BOOLEAN _po_flush(PC_FILE *pfile) /*__fn__*/
{
BOOLEAN ret_val;
ret_val = TRUE;
/* Convert to native. Overwrite the existing inode.Set archive/date */
if (pfile->needs_flush)
{
if (pc_update_inode(pfile->pobj, TRUE, TRUE))
{
pfile->needs_flush = FALSE;
/* Flush the file allocation table */
if (!pc_flushfat(pfile->pobj->pdrive->driveno))
ret_val = FALSE;
}
}
return(ret_val);
}
#endif
RTFS_FILE(flush.c, po_flush)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
/****************************************************************************
PO_FLUSH - Flush a file.
Description
Flush the file updating the disk.
Returns
Returns TRUE if all went well otherwise it returns FALSE and xn_getlasterror() is set to
one of these values
PENBADF - Invalid file descriptor
PENOSPC - IO error occured
****************************************************************************/
BOOLEAN po_flush(PCFD fd) /*__fn__*/
{
PC_FILE *pfile;
BOOLEAN ret_val;
int p_errno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
OS_FS_ENTER()
/* Start by assuming failure */
ret_val = FALSE;
p_errno = PEBADF;
/* Get the FILE. must be open for write */
pfile = pc_fd2file(fd, PO_WRONLY|PO_RDWR);
if (pfile)
{
OS_CLAIM_LOGDRIVE(pfile->pobj->pdrive->driveno) /* Register drive in use */
/* Claim exclusive access on flush */
ret_val = _po_flush(pfile);
if (!ret_val)
p_errno = PENOSPC;
OS_RELEASE_LOGDRIVE(pfile->pobj->pdrive->driveno)
}
/* Restore the kernel state */
set_errno(p_errno);
OS_FS_EXIT()
return(ret_val);
}
#endif
RTFS_FILE(close.c, po_close)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/****************************************************************************
PO_CLOSE - Close a file.
Description
Close the file updating the disk and freeing all core associated with FD.
Returns
Returns 0 if all went well otherwise it returns -1 and xn_getlasterror() is set to
one of these values
PENBADF - Invalid file descriptor
PENOSPC - IO error occured
****************************************************************************/
int po_close(PCFD fd) /*__fn__*/
{
PC_FILE *pfile;
int ret_val;
int driveno;
int p_errno;
CHECK_MEM(int, -1) /* Make sure memory is initted */
OS_FS_ENTER()
if ( (pfile = pc_fd2file(fd, 0)) == 0)
{
p_errno = PEBADF;
ret_val = -1;
}
else
{
driveno = pfile->pobj->pdrive->driveno;
OS_CLAIM_LOGDRIVE(driveno) /* Register drive in use */
ret_val = 0;
p_errno = 0;
#if (RTFS_WRITE)
if (pfile->flag & ( PO_RDWR | PO_WRONLY ) )
{
if (!_po_flush(pfile))
{
p_errno = PENOSPC;
ret_val = -1;
}
}
#endif
/* Release the FD and its core */
pc_freefile(fd);
OS_RELEASE_LOGDRIVE(driveno)
}
set_errno(p_errno);
/* Restore the kernel state */
OS_FS_EXIT()
return(ret_val);
}
RTFS_FILE(mv.c, pc_mv)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/***************************************************************************
PC_MV - Rename a file.
Description
Renames the file in path (name) to newname. Fails if name is invalid,
newname already exists or path not found.
01-07-99 - Rewrote to support moving files between subdirectories
no longer supports renaming subdirectories or volumes
Returns
Returns TRUE if the file was renamed. Or no if the name not found.
***************************************************************************/
#if (RTFS_WRITE)
/* Rename a file */
BOOLEAN pc_mv(char *old_name, char *new_name) /*__fn__*/
{
int old_driveno;
DROBJ *old_obj;
DROBJ *old_parent_obj;
char path[EMAXPATH];
char filename[FILENAMESIZE];
char fileext[4];
int new_driveno;
DROBJ *new_obj;
DROBJ *new_parent_obj;
BOOLEAN ret_val;
CLUSTERTYPE cluster; /* FAT32 */
int p_errno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
OS_FS_ENTER() /* Must be last line in declarations */
/* Get the drive and make sure it is mounted */
old_driveno = check_drive(old_name);
if (old_driveno < 0)
{
OS_FS_EXIT()
return(FALSE);
}
old_obj = 0;
old_parent_obj = 0;
new_obj = 0;
new_parent_obj = 0;
ret_val = FALSE;
p_errno = PENO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -