📄 apiutil.c
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1996
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* APIUTIL.C - Contains support code for user api level source code.
The following routines are included:
pc_fd2file - Map a file descriptor to a file structure.
pc_allocfile - Allocate a file structure.
pc_freefile - Release a file structure.
pc_free_all_fil - Release all file structures for a drive.
pc_log_base_2 - Calculate log2(N).
pc_get_cwd - Determine cwd string from current directory inode.
pc_upstat - Copy directory entry info to a user's stat buffer
_synch_file_ptrs - make sure file pointers are synchronyzed
get_disk_volume - Get the voulme label from a boot block
*/
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include "pcdisk.h"
#endif
RTFS_FILE(chkdrive.c, check_drive)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/* Check if a drive id is valid and mount the drive. This is an internal
routine that is called by other api calls */
int check_drive(char *name) /*__fn__*/
{
int driveno;
set_errno(0);
/* Get the drive and make sure it is mounted */
if (pc_parsedrive( &driveno, name))
{
//OS_CLAIM_LOGDRIVE(driveno) /* Register drive in use */
//if (!check_media_entry(driveno) || !pc_drno2dr(driveno))
//{
// OS_RELEASE_LOGDRIVE(driveno)
// set_errno(PEDEVICE);
// return(-1);
//}
//OS_RELEASE_LOGDRIVE(driveno)
}
else
{
set_errno(PEDEVICE);
return(-1);
}
return(driveno);
}
/* written by Meter.chen */
int mount_drive(char *name)
{
int driveno;
set_errno(0);
/* Get the drive and make sure it is mounted */
if (pc_parsedrive( &driveno, name))
{
OS_CLAIM_LOGDRIVE(driveno) /* Register drive in use */
if (!check_media_entry(driveno) || !pc_drno2dr(driveno))
{
OS_RELEASE_LOGDRIVE(driveno)
set_errno(PEDEVICE);
return(-1);
}
OS_RELEASE_LOGDRIVE(driveno)
}
else
{
set_errno(PEDEVICE);
return(-1);
}
return(driveno);
}
/* pc_i_dskopen() and get_disk_volume() are used to mount a disk.
they are called by the check media code */
BOOLEAN pc_i_dskopen(int driveno) /*__fn__*/
{
BOOLEAN ret_val;
DDRIVE *pdr;
ret_val = pc_dskinit((int)driveno);
if (ret_val)
{
pdr = pc_drno2dr((int)driveno);
if (pdr)
{
get_disk_volume((int)driveno, pdr->volume_label, &pdr->volume_serialno);
}
}
return(ret_val);
}
BOOLEAN get_disk_volume(int driveno, byte *pvollabel, dword *pserialno) /*__fn__*/
{
BLKBUFF *rbuf;
BOOLEAN ret_val;
rbuf = pc_scratch_blk();
if (!rbuf)
return(FALSE);
*pvollabel = 0;
if (devio_read(driveno, 0, rbuf->data , 1, FALSE))
{
ret_val = TRUE;
*pserialno = to_DWORD(&rbuf->data[0x27]); /* Volume serial # */
#if (FAT32)
/* if(pbl0->numroot==0) - see gblk0 */
if (to_WORD(&rbuf->data[0x11])==0)
copybuff( pvollabel,&rbuf->data[0x47],11); /* Volume label (4.0) */
else
#endif
copybuff( &pvollabel[0],&rbuf->data[0x2b],11); /* Volume label (4.0) */
pvollabel[11] = 0;
}
else
ret_val = FALSE;
pc_free_buf(rbuf, TRUE);
return(ret_val);
}
RTFS_FILE(fd2file.c, pc_fd2file)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/****************************************************************************
Miscelaneous File and file descriptor management functions
These functions are private functions used by the po_ file io routines.
pc_fd2file -
Map a file descriptor to a file structure. Return null if the file is
not open. If an error has occured on the file return NULL unless
allow_err is true.
pc_allocfile -
Allocate a file structure an return its handle. Return -1 if no more
handles are available.
pc_freefile -
Free all core associated with a file descriptor and make the descriptor
available for future calls to allocfile.
pc_free_all_fil -
*****************************************************************************/
/* Map a file descriptor to a file structure. Return null if the file is
not open or the flags don't match (test for write access if needed).
*/
PC_FILE *pc_fd2file(PCFD fd,int flags) /*__fn__*/
{
PC_FILE *pfile;
PC_FILE *pret_val;
OS_CLAIM_FSCRITICAL()
pret_val = 0;
if (0 <= fd && fd <= pc_nuserfiles())
{
pfile = mem_file_pool+fd;
if (pfile && !pfile->is_free)
{
/* If flags == 0. Any access allowed. Otherwise at least one
bit in the file open flags must match the flags sent in */
if (!flags || (pfile->flag&flags))
{
pret_val = pfile;
}
}
}
OS_RELEASE_FSCRITICAL()
return(pret_val);
}
RTFS_FILE(allocfil.c, pc_allocfile)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/* Assign zeroed out file structure to an FD and return the handle. Return
-1 on error. */
PCFD pc_allocfile(void) /*__fn__*/
{
PC_FILE *pfile;
PCFD i;
OS_CLAIM_FSCRITICAL()
pfile = mem_file_pool;
for (i=0;i<pc_nuserfiles();i++, pfile++)
{
if (pfile->is_free)
{
pc_memfill(pfile, sizeof(PC_FILE), (byte) 0);
OS_RELEASE_FSCRITICAL()
return(i);
}
}
OS_RELEASE_FSCRITICAL()
return (-1);
}
RTFS_FILE(freefile.c, pc_freefile)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/* Free core associated with a file descriptor. Release the FD for later use */
void pc_freefile(PCFD fd) /*__fn__*/
{
PC_FILE *pfile;
if ( (pfile = pc_fd2file(fd, 0)) == 0)
return;
if (pfile->pobj)
pc_freeobj(pfile->pobj);
pfile->is_free = TRUE;
}
RTFS_FILE(freallfi.c, pc_free_all_fil)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
RTFS_FILE(freallfi.c, pc_free_all_fil)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#define ENUM_FLUSH 1
#define ENUM_TEST 2
#define ENUM_FREE 3
/* Release all file descriptors associated with a drive and free up all core
associated with the files
called by dsk_close
*/
int pc_enum_file(DDRIVE *pdrive, int chore) /*__fn__*/
{
PC_FILE *pfile;
PCFD i;
int dirty_count;
dirty_count = 0;
for (i=0; i < pc_nuserfiles(); i++)
{
pfile = pc_fd2file(i, 0);
if (pfile)
{
if ((pfile->pobj) && (pfile->pobj->pdrive == pdrive))
{
/* print a debug message since in normal operation
all files should be close closed before closing the drive */
#if (RTFS_WRITE)
if (chore == ENUM_FLUSH)
{
if (!_po_flush(pfile))
return(-1);
}
#endif
if (chore == ENUM_TEST)
{
if (pfile->needs_flush)
dirty_count += 1;
}
if (chore == ENUM_FREE)
{
pc_freefile(i);
}
}
}
}
return(dirty_count);
}
/* Release all file descriptors associated with a drive and free up all core
associated with the files
called by dsk_close
*/
void pc_free_all_fil(DDRIVE *pdrive) /*__fn__*/
{
pc_enum_file(pdrive, ENUM_FREE);
}
#if (RTFS_WRITE)
/* Flush all files on a drive */
BOOLEAN pc_flush_all_fil(DDRIVE *pdrive) /*__fn__*/
{
if (pc_enum_file(pdrive, ENUM_FLUSH) == 0)
return(TRUE);
else
return(FALSE);
}
#endif
/* Test the dirty flag for all files */
int pc_test_all_fil(DDRIVE *pdrive) /*__fn__*/
{
return(pc_enum_file(pdrive, ENUM_TEST));
}
RTFS_FILE(cwd.c, pc_cwd)
#ifndef __PCDISK__ /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
/***************************************************************************
PC_CWD - Get the current working directory for a drive,
Description
Return the current directory inode for the drive represented by ddrive.
***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -